程序设计之如何计算多边形的面积

时间:2016-10-07
今天在论坛看到这样一个问题,程序输入一系列的点,按输入顺序首尾相连构成一个多边形,如何求这个多边形的面积?本文章将通过编程的思路和设计理念来向大家介绍如何通过代码来实现计算多边形的面积,需要的朋友可以参考一下。

思路:

其实方法很简单,定积分。我还是简单解释一下,如果是没有读过高等数学的朋友,也让你大致明白。

定积分的本质是求和,计算f(x)在积分区间[a,b]上的一个和S,首先把积分区间分成n份,这样的分法记为λ,记Δ(λ)=max{Δx|[xi -1,xi]},也就是所有这些分成的小段中长度最大的一段的长,如果当Δ→0的时候,和式S=∑f(θ)Δx (θ∈[xi-1,xi])的极限如果存在的话,就称其为f(x)在[a,b]上的定积分,记为
b
∫f(x)dx
a
其意义从几何上解释,就是f(x)的曲线与x轴、直线x=a,x=b围成的图形的面积。
现在要求的多边形是由线段组成的,只要把所有的线段都求定积分,最后把和加起来,就是多边形的面积。这个推论的证明从略。值得注意的是,用定积分求的面积有正负之分,即:
b         a
∫f(x)dx=-∫f(x)dx
a         b
从a积到b,与从b积到a只相差一个负号。

线段定积分的计算公式的推导

给出两个点,如何求这两点连成的线段的定积分值呢?
直线的方程可以用y=kx+b表示,所以围成的面积
S=
x2
∫(kx+b)dx
x1
=k/2(x2^2-x1^2)+b(x2-x1)

而斜率k=(y2-y1)/(x2-x1)
截距b=y1-kx1=y1-x1(y2-y1)/(x2-x1),代入前式得
S=(y2-y1)(x2+x1)/2+y1(x2-x1)-x1(y2-y1)
=(x2-x1)(y1+y2)/2
这让我想到一个初等公式,梯形面积公式,y1,y2看成上下底,(x2-x1)看成是高,上底加下底乘高除二,对直线定积分得到的正是这个梯形的面积。这样走了一个大弯又回到初中了。

实例:

设Ω是m边形(如下图),顶点程序设计之如何计算多边形的面积沿边界正向排列,,坐标依次为

程序设计之如何计算多边形的面积

建立Ω的多边形区域向量图。

由图知坐标原点与多边形任意相邻的两个顶点构成一个三角形,而三角形的面积可由三个顶点构成的两个平面向量的外积求得。

任意多边形的面积公式

程序设计之如何计算多边形的面积

多边形计算公式的计算和原点的选取没有关系,通常可以选点(0,0)或者多边形的第一个点(这个时候比较直观了,看起来就是把多边形分成一个个三角形和加起来,读者自己可以画个图)就可以了。

程序设计之如何计算多边形的面积

//任意多边形的面积计算  
  
#include <iostream>  
#include <utility>  
#include <cmath>  
using std::cout;  
using std::cin;  
using std::endl;  
  
typedef std::pair<double ,double> point;  
  
#pragma warning(disable:4244)  
  
double det(point p0,point p1,point p2)  
{  
    return (p1.first-p0.first)*(p2.second-p0.second)-(p1.second-p0.second)*(p2.first-p0.first);  
}  
  
double ploygon_area(int n,point p[])    
{  
    double s=0.0f;  
    int i=1;  
    for(;i < n-1;i++)  
        s += det(p[0],p[i],p[i+1]);  
    return 0.5*fabs(s);  
}  
  
int main(int argc, char *argv[])  
{  
  
    int i,n;  
    double s;  
    point *points = NULL;  
  
    cout<<"Enter the number of edges of the polygon <n>:";  
    cin>>n;  
    if(n < 2){  
        exit(1);  
    }  
  
    points = (point *)malloc(n*sizeof(point));  
  
    for(i=0; i<n; i++){  
        cout<<endl<<"points["<<i<<"]=";  
        cin>>points[i].first>>points[i].second;  
    }  
  
    s=ploygon_area(n, points);  
    cout<<"The area is:"<<s<<std::endl;  
  
    if(points)  
        free(points);  
  
    return 1;  
}