計算任意多邊形的面積

 

 

1. 對於凸多邊形,很容易計算,以下圖,以多邊形的某一點爲頂點,將其劃分紅幾個三角形,計算這些三角形的面積,而後加起來便可。已知三角形頂點座標,三角形面積能夠利用向量的叉乘來計算。算法

  對於凹多邊形,若是仍是按照上述方法劃分紅三角形,以下圖,多邊形的面積 = S_ABC + S_ACD + S_ADE, 這個面積明顯超過多邊形的面積。優化

  咱們根據二維向量叉乘求三角形ABC面積時,利用的是:spa

  這樣求出來的面積都是正數,可是向量叉乘是有方向的,即image 是有正負的,若是把上面第三個公式中的絕對值符號去掉,即image ,那麼面積也是有正負的。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);
}
相關文章
相關標籤/搜索