之前,應朋友所托,完成個四邊形面積計算程序,於是不由自主考慮來個擴展,解決任意多邊形面積的計算。
一開始想到了某定點的三角形剖分,但遇到凹凸多邊形引發的多種情況,過於復雜,放棄。
后來想到用圖形學中填充算法中的掃描線方法,切分成梯形與三角形,將交點存入活性邊表后再計算面積,感覺也較復雜,放棄。
再然后,找到個計算幾何大神O’Rourke在1998年公開的成果。
*(書名:Computational Geometry in C,第二版P20)*
1-原理介紹
上書中給出定理:
任意多邊形的面積可由任意一點與多邊形上依次兩點連線構成的三角形矢量面積求和得出。
矢量面積=三角形兩邊矢量的叉乘。
如下圖:
按定理,多邊形面積由P點與A-G的各頂點連接所構成的三角形矢量面積構成,假定多邊形頂點坐標順序為A-G,逆時針為正方向,則有如下結論:
PAB,PBC,PCD均為順時針,面積為負;
PDE,PEF,PFG,PGA均未逆時針,面積為正;
但無論正負,均可通過P點與頂點連線的矢量叉乘完成,叉乘結果中已包含面積的正負。
2-程序設計
采用C++的vector(動態數組)存儲頂點坐標。
為方便計算,直接將P點定為原點(0,0),則多邊形頂點xy坐標即為向量在xy上分量。
循環計算多邊形頂點坐標每一點與下一點之間的線段,及這兩點與P連線的矢量所圍成的三角形面積。
計算面積的函數代碼如下:
iArea=iArea+(vecPoly[iCycle].x*vecPoly[(iCycle+1) % iCount].y-vecPoly[(iCycle+1) % iCount].x*vecPoly[iCycle].y); int intAreaCalc(vector<myPoint> &vecPoly) { int iCycle,iCount,iArea; iCycle=0; iArea=0; iCount=vecPoly.size(); for(iCycle=0;iCycle<iCount;iCycle++) { iArea=iArea+(vecPoly[iCycle].x*vecPoly[(iCycle+1) % iCount].y-vecPoly[(iCycle+1) % iCount].x*vecPoly[iCycle].y); } return abs(0.5*iArea); }
注意,要注意的是最后一個頂點,要與第一個頂點練成三角形,可將循環變量對頂點總數求同余,則循環過程中的最后一點+1后,自然會成為第一個頂點,上述代碼中的“% iCount”即為解決此問題。
完整程序,請下載工程文件。
http://files.cnblogs.com/vbspine/sdkPoly.rar
Ps:上述程序在Win7x64,VS2008環境下編譯通過。