日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

计算几何之多边形

發布時間:2024/1/8 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 计算几何之多边形 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近解決一個多邊形帶洞的問題,需要判斷多邊形的頂點順序,順便復習下計算幾何的一些基礎知識。。
判斷頂點順序需要計算多邊形的面積,面積有正負之分,符號決定了順時針CW還是逆時針CCW。計算面積兩種思路:
- 直角梯形的思路
- 向量叉乘

直角梯形思路

任何一個邊p0p1,兩個頂點向x軸投垂線,構成了直角梯形。它的面積是

(p1.x – p0.x) * (p1.y + p2.y) / 2.0


面積符號受deltaX,averageY影響。二者綜合影響。

下圖中,多邊形面積等于所有邊與x軸構成直角梯形面積總和。N個頂點,則N個邊的面積之和,尤其注意首尾頂點(n-1, 0)的 這個線段的面積需要考慮進去。。

上圖中,多邊形頂點順序為順時針ABCDEFG,
TopAreas是AB,BC,CD,DE 與x軸構成的梯形,面積都大于0;
BottomAreas是EF,FG,GA與x軸構成的梯形,deltax為負,面積都小于0;最終多邊形面積為正。

因此

這種方式下,多邊形頂點順序為逆時針,則面積為負值;順時針時候,面積為正值。

向量叉乘的方式

向量叉乘
最經簡單的例子,

unit_x(1, 0, 0) cross unit_y(0, 1, 0) = unit_z(0, 0, 1)

叉乘的右手法則:右手四指,從a開始以不超過180的轉角握向b,大拇指的指向就是叉乘結果向量的方向。
2D向量叉乘的物理意義:a向量叉乘b向量的模,代表|b|*sin為高,a為底的三角形面積。面積可以有符號,叉乘向量是z軸正向時,面積為正,否則為負。

多邊形的面積計算,多邊形每個邊兩個端點跟原點組成一系列三角形,它們的面積有正負,所面積之和就是多邊形的面積。

右圖中,多邊形是逆時針方向,ABCDEFG
第一個三角形:ABP面積為負,為什么呢?AP.cross(BP) 向量的方向是z軸負方向。
最后一個三角形GAP,面積為正,why?GP.cross(AP) 向量的方向是z軸正方向。

結論

多邊形頂點順序為逆時針時,計算的面積為正;順時針時,面積為負值。

代碼

// http://www.cnblogs.com/void/archive/2011/04/17/2018729.html bool IsPolygonClockWise(const std::vector<Point_Double>& vPolygon) {// compute area of a contour/polygonint n = vPolygon.size();double A = 0.0;for(int p=n-1,q=0; q<n; p=q++){A+= vPolygon[p].x * vPolygon[q].y - vPolygon[q].x * vPolygon[p].y;}double Area = A * 0.5;// we want a counter-clockwise polygon in Vif ( 0.0 < Area ){return false;}else{return true;} }// http://csharphelper.com/blog/2014/07/calculate-the-area-of-a-polygon-in-c/ bool IsPolygonClockWise_WhenYUp(TXMapPoint* polygon, int count) {double rst = 0.0;#if 1// first point must be equal to last point.for (int i = 0; i < count; i++){int next = (i + 1) % count;double dx = polygon[next].x - polygon[i].x;double dy = polygon[next].y + polygon[i].y;rst += (dx * dy);// overflow issue.// rst += ( (polygon[next].x - polygon[i].x) * (polygon[next].y + polygon[i].y) / 2.0 );} #else// bad version// 沒有計算首尾兩個點構成的面積。。。for (int i = 1; i <count; i++){double dx = (polygon[i].x - polygon[i - 1].x);double ay = (polygon[i].y + polygon[i - 1].y);rst += (dx * ay);} #endifif (rst >= 0){return true;}else{return false;} }

踩過的坑
地圖中坐標很大,如果使用int存儲,計算面積的時候有越界的可能。越界后結果為負數,也會影響到最終的計算結果。

function 1--------- p q 2, 0 0, 1 1, 22x * 0y - 0x * 2y 0x * 1y - 1x * 0y 1x * 2y - 2x * 1yfunction 2--------- (1x - 0x) * (1y + 0y) = 1x * 1y + 1x * 0y - 0x * 1y - 0x * 0y2x * 2y + 2x * 1y - 1x * 2y - 1x * 1y(0x - 2x) * (0y + 2y) = 0x * 0y + 0x * 2y - 2x * 0y - 2x * 2yoptim: 1x * 0y - 0x * 1y 2x * 1y - 1x * 2y 0x * 2y - 2x * 0y ---------
  • 第一種方式計算量更加少
  • 第二種方式有點冗余,循環中每次的計算結果中有可以抵消的部分
  • 第二種優化的結果與第一種正好差一個符號

OpenGL模板測試渲染任意凹多邊形

如下圖,多邊形1234567。A,D,F區域組成了多邊形,且這三個區域都是由奇數個三角形覆蓋;其他區域由偶數個,或者0個三角形覆蓋。如圖中右邊的列表,B由123,134兩個三角形覆蓋。

選擇任意一點P作為基準點,分別渲染P12,P23,P34,P45,P56,P67,P71 三角形。多邊形內部的區域被填充了奇數次,外部的區域被填充了偶數次。
OpenGL渲染凹多邊形的思路:借助幀緩沖區,兩次渲染多邊形的三角形列表。

  • 禁止寫入顏色緩沖區,清空幀緩沖區;
  • 遍歷三角形渲染,幀緩沖函數采用GL_INVERT。這個函數的效果是,三角形渲染時,它覆蓋的每個像素的幀緩沖區值,都在0和非0之間翻轉。所有三角形畫完,像素被覆蓋了偶數次的話,幀緩沖區對應位置的值是0,奇數次的話幀緩沖對應的值是非零。
  • 畫一個大多邊形,能夠包含整個多邊形,例如它的boundingbox,但是只允許幀緩沖區中非零的區域通過測試。
  • 點評

    • 技術雖有點過時了,這種技術適應任何復雜帶洞的多邊形渲染。
    • 相比較直接凹多邊形三角化后渲染,重疊地方的被多次柵格化,性能消耗較大。opengl渲染的步驟,頂點處理,柵格化,片段處理,然后裁剪測試,alpha測試,模板測試(幀緩沖區),深度測試(深度緩沖區)。

    ref:http://glprogramming.com/red/chapter14.html#name13

    總結

    以上是生活随笔為你收集整理的计算几何之多边形的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。