1. 對於凸多邊形,很容易計算,以下圖,以多邊形的某一點爲頂點,將其劃分紅幾個三角形,計算這些三角形的面積,而後加起來便可。已知三角形頂點座標,三角形面積能夠利用向量的叉乘來計算。算法
對於凹多邊形,若是仍是按照上述方法劃分紅三角形,以下圖,多邊形的面積 = S_ABC + S_ACD + S_ADE, 這個面積明顯超過多邊形的面積。優化
咱們根據二維向量叉乘求三角形ABC面積時,利用的是:spa
這樣求出來的面積都是正數,可是向量叉乘是有方向的,即 是有正負的,若是把上面第三個公式中的絕對值符號去掉,即 ,那麼面積也是有正負的。3d
物理解釋:反應在上面第二個圖中,S = S_ABC + S_ACD + S_ADE,若是S_ABC和S_ADE是正的,那麼S_ACD是負的,這樣加起來恰好就是多邊形的面積。對於凸多邊形,全部三角形的面積都是同正或者同負。code
若是咱們不以多邊形的某一點爲頂點來劃分三角形而是以任意一點,以下圖,這個方法也是成立的:S = S_OAB + S_OBC + S_OCD + S_ODE + S_OEA。計算的時候,當咱們取O點爲原點時,能夠簡化計算。blog
當O點爲原點時,根據向量的叉積計算公式,各個三角形的面積計算以下:get
S_OAB = 0.5*(A_x*B_y - A_y*B_x) 【(A_x,A_y)爲A點的座標】it
S_OBC = 0.5*(B_x*C_y - B_y*C_x)class
S_OCD = 0.5*(C_x*D_y - C_y*D_x)方法
S_ODE = 0.5*(D_x*E_y - D_y*E_x)
S_OEA = 0.5*(E_x*A_y - E_y*A_x)
代碼以下:
struct Point2d { double x; double y; Point2d(double xx, double yy): x(xx), y(yy){} }; //計算任意多邊形的面積,頂點按照順時針或者逆時針方向排列 double ComputePolygonArea(const vector<Point2d> &points) { int point_num = points.size(); if(point_num < 3)return 0.0; double s = 0; for(int i = 0; i < point_num; ++i) s += points[i].x * points[(i+1)%point_num].y - points[i].y * points[(i+1)%point_num].x; return fabs(s/2.0); }
該算法還能夠優化一下,對上面的式子合併一下同類項:
S = S_OAB + S_OBC + S_OCD + S_ODE + S_OEA =
0.5*[A_y*(E_x-B_x) + B_y*(A_x-C_x) + C_y*(B_x-D_x) + D_y*(C_x-E_x) + E_y*(D_x-A_x)]
這樣減小了乘法的次數,代碼以下:
double ComputePolygonArea(const vector<Point2d> &points) { int point_num = points.size(); if(point_num < 3)return 0.0; double s = points[0].y * (points[point_num-1].x - points[1].x); for(int i = 1; i < point_num; ++i) s += points[i].y * (points[i-1].x - points[(i+1)%point_num].x); return fabs(s/2.0); }