1. 程式人生 > >求解多邊形面積2S= Σ【Xi (Yi+1-Yi-1)】,(i屬於1~n),公式解析及編程實現

求解多邊形面積2S= Σ【Xi (Yi+1-Yi-1)】,(i屬於1~n),公式解析及編程實現

poi logs 驗證 地圖 class view hide 對比 turn

yogurt今天要個大家分享一個基礎的二維空間多邊形面積求算方法,主要也是為了下一篇《橢球體上某區域面積的求算,及Albers投影與墨卡托投影後該區域面積對比》打一個基礎。關於投影的相關過程及編程方法,大家可以參考我之前寫過的《.gen地圖文件的投影編程實現(以墨卡托投影和蘭伯特投影為例)》http://www.cnblogs.com/to-sunshine/p/6048438.html。

下面和大家分析一下算法思路吧:

==========================yogurt小課堂開課了=========================

首先,我們知道一個二維多邊形可以被分解成多個三角形,多邊形的面積即為所有三角形的面積之和了。然後就是怎麽將求解三角形的面積與坐標點聯系起來了,因為我們在程序中只給出了多邊形每個點的坐標而已,這和我們手動計算不一樣,畢竟計算機可沒這麽智能。

三角形的面積 S = 1/2 a X h,這裏假設a為三角形的底邊長,h為三角形的高。那麽這裏 h =b X sin夾角 ,這樣便讓求取面積相關因子變到了三角形的邊和夾角上。即 S = 1/2 a X b X sin夾角。看到這裏相信聰明的你一定看出來了,a X b X sin夾角,很眼熟啊!對,它等於 | 向量a X 向量b | ,自然而然的,向量便把幾何的圖形與點坐標聯系起來了。

所以,三角形的面積 S = 1/2 | 向量a X 向量b | ,而 | 向量a X 向量b | = X1Y2 - X2Y1 ,如果想要把兩條邊的交點看做原點的話,那麽 | 向量a X 向量b | =(Xa-Xo)(Yb-Yo)- (Xb-Xo)(Ya-Yo)。為了不讓分數參與運算,等式兩邊同時乘2,得到 2S = (Xa-Xo)(Yb-Yo)- (Xb-Xo)(Ya-Yo)。

然後,我們假設在多邊形外面有一個點P,多邊形有N個頂點(V0~Vn-1)。要知道n-1是多邊形的最後一個頂點,那麽Vn就是V0,Vn+1就是V1。

多邊形的每兩個點與這個P點相連都可以組成一個三角形,你會發現,從前一個點到後一個點是順時針方向時,這個三角形面積為正的話,那麽當從前一個點到後一個點是逆時針方向時,三角形面積為負。當正負相抵後,剩下的正好就是多邊形的面積!如下圖:

技術分享

因此,得到多邊形面積 2S = 三角形(PV0V1) + 三角形(PV1V2) + …… + 三角形(PVn-2Vn-1) + 三角形(PVn-1V0)。

為了方便計算三角形的面積,我們選擇P點坐標為(0,0),那麽 2S =【 Σ三角形(PViVi+1)】+ 三角形(PVi+1V0),(i屬於0到n-2)。下面就有一個比較復雜的換算工作,是為了簡化等式,方便計算:

技術分享

技術分享

最後,我們得到 2S = Σ【Xi (Yi+1-Yi-1)】,(i屬於1~n)。

=================================下課了================================

原理講完啦,下面來給大家附上求解多邊形面積的代碼:

假設第一個多邊形幾個頂點坐標分別是(4,6), (4,-4), (8, -4), (8,-8), (-4, -8), (-4,6), (4,6),用未化簡得公式求解;第二個多邊形的幾個頂點坐標分別是(3,4), (5,11), (12,8), (9,5), (5,6),用化簡後的公式求解。

技術分享
// area.cpp : 定義控制臺應用程序的入口點。
//

#include "stdafx.h"
#include<math.h>

typedef struct
{
    int x,y;
}point;

int _tmain(int argc, _TCHAR* argv[])
{
    point p[7];
    p[0].x=4;p[0].y=6;
    p[1].x=4;p[1].y=-4;
    p[2].x=8;p[2].y=-4;
    p[3].x=8;p[3].y=-8;
    p[4].x=-4;p[4].y=-8;
    p[5].x=-4;p[5].y=6;
    p[6].x=4;p[6].y=6;

    int area=0;
    for(int i=0;i<6;i++)
    {
        area+=(p[i].x+p[i+1].x)*(p[i+1].y-p[i].y);
    }
    area =abs(area/2);
    printf("The area of graph1 is %d",area);

    point p2[6];
    p2[0].x = 3; p2[0].y = 4;
    p2[1].x = 5; p2[1].y = 11;
    p2[2].x = 12;p2[2].y = 8;
    p2[3].x = 9; p2[3].y = 5;
    p2[4].x = 5; p2[4].y = 6;
    p2[5].x = 3; p2[5].y = 4;

    int area2 = 0;
    for (int j = 0; j<5; j++)
    {
        area2 += (p2[j].x + p2[j + 1].x)*(p2[j + 1].y - p2[j].y);
    }
    
    area2 = abs(area2 / 2);
    printf("\nThe area of graph2 is %d", area2);

    return 0;
}
View Code

結果如下:

技術分享

大家也可以手動驗證一下,程序計算的對不對~~

求解多邊形面積2S= Σ【Xi (Yi+1-Yi-1)】,(i屬於1~n),公式解析及編程實現