C++代码计算任意多边形的面积

        刚刚开通了博客,今天正好有时间来完成自己的第一篇博客文章。希望对有需要的朋友有所帮助。   

        今天写了一个小代码:计算任意多边形的面积。临近毕业,毕设也忙得很,还好最近完成的差不多了,就差写论文了,今天突然想到写博客是个挺有趣的东西,于是就过来写我的第一篇。   

       好!步入正题,不过还是先介绍一下本博客的背景。也是关于毕设的事,我的一个同学说要我帮他想想怎样计算一个滑坡面的面积。大家都知道滑坡面是一个不规则图形,所以在计算之前首先需要处理这个不规则图形,把它近似成某个多边形,然后再计算多边形的面积。当然这样做只有近似得的多边形的边数越多,精度才会越高,所以近似成的多边形可能是任意边形(三边,四边几十边不等)。下面我们就先来介绍我的思路。

  

                                                                                  图1

                                                                图2

        如图所示,要计算多边形面积,首先要将n边形划分成(n-2)个三角形,因为三边形以上的多边形没有直接的公式计算。分隔的方法有很多,我选择了以上方法,并且我们约定输入顶点坐标的顺序按顺时针方向输入。这里先暂时不考虑起点问题(即先不考虑何点为图中点“1”),假设我们已经找到点“1”,这时就会分隔成(9-2=7)个三角形,如图。如果多边形的顶点都是向外凸的,那么计算很简单,直接计算7个三角形的面积(【123】【134】【145】【156】【167】【178】【189】)然后相加即可(图2),若存在向里凹的情况(图1,只考虑【134】【189】的情况,像567这三个点6明显下凹,但是当我们以1为起始点时计算面积并不影响),那么计算面积就会有些麻烦,下面我们来看看怎样处理这种情况(存在【134】【189】的情况)。先来看【134】,3往里凹,那么可以看到我们在计算【123】时就已经把【134】的右下部分计算了进去,再算【134】就会多算左下部分,然后我们再看:当计算【145】时又计算了一次【134】的右下部分(共三次了),与此同时还计算本不属于多边形的部分,即【134】的左上部分。这时我们只要这样处理就可解决,把【134】的面积取负,这样【134】的右下部分就会抵消掉【145】多算的部分,保留【123】计算的,而【134】的左上部分就会抵消掉【145】多算的本属于多边形面积的部分(【134】左上部分)。这样就能实现多边形面积的计算了,即“凸三角形”面积取正,“凹三角形”取负,最后将(n-2)个三角的面积带符号相加。

        上面我们已经介绍了多边形的计算方法,但是还有一个问题,怎样找到点“1”,很简单,只要遍历n个点的纵坐标找出纵坐标为最小的点,然后以这点为点“1”,然后再按顺时针重新组织编号(具体代码如何实现自己想办法,当然下面的代码我是那样处理的,注释很清楚)。

        刚刚又说了如何找到点“1”,但是还有一个很重要的问题:如何判断三角形是凹是凸,方法应该有很多,下面介绍我的方法。因为我的思路是将第一个点定为纵坐标最小的点(即最低(靠下)点),然后可以考虑斜率的大小关系就可以辨别是凹是凸了。具体说一下吧,以图1【134】(为凹)为例,此时直线“13”的斜率小于直线“14”的斜率,细心地你会发现此时着两条直线的斜率都是小于零的,但是当两条直线异号或者都到大于零时是一样的吗,回答是:不太一样。既然你想到这里相信你也有这个能力去解决这个问题了,当都大于零时和都小于零是一样的,当斜率不存在和异号的情形就不解释了,具体看代码或者自己想办法吧。下面附上代码以及运行结果图,很详细,句句有注释,用心良苦啊(呲牙)。


(环境:vc++6.0,其他C++环境也可以,适当修改而已)

#include<iostream>
#include<math.h>
using namespace std;
float calculateTwoPointArea(float x1,float x2,float x3,float y1,float y2,float y3);//声明函数
/**
*  main()函数,程序入口,进行输入坐标点操做以及计算多边形面积
*  形参:无
*  返回:无
*/
void main(){
    int count;//多边形的边数(或顶点数)
    float point[1000][2];//未整理点集
    float point2[1000][2];//已整理点集
    float comp;//存比较数
    int locat;//存最低点位置
 float x1,x2,x3,y1,y2,y3;//存放三角形的顶点坐标
 float k1,k2;//存放斜率
 static float Sthree=0;//存放三角形面积(静态变量,避免被销毁)
    do{//要求输出3-1000的数
     cout<<"请输入点的个数(3-1000个点)"<<endl;
     cin>>count;
    }while(count>1000||count<3);
    cout<<"请!!!顺时针!!!输入"<<count<<"个点集:(x,y)"<<endl;
    for(int i=0;i<count;i++){
     cout<<"请输入第"<<(i+1)<<"点的坐标(x,y):"<<endl;
     for(int j=0;j<2;j++){
      cin>>point[i][j];//输入坐标
   
  }
    }
    //查询最低点
    comp=point[0][1];//赋予第一点
    locat=0;//第一个位置
    for(int k=1;k<count;k++){
        if(point[k][1]<comp){//只比较y
         locat=k;
  }
    }
    //整理点集point2[][],把locat位置的点当成第一点
    for(int s=0;s<(count-locat);s++){//赋予point2[][]以locat后半段(包括locat)
     for(int t=0;t<2;t++){
         point2[s][t]=point[s+locat][t];
  }
    }
    for(int p=0;p<locat;p++){//赋予point2[][]以locat前半段
     for(int q=0;q<2;q++){
         point2[count-locat+p][q]=point[p][q];
  }
    }
    开始计算面积/
    x1=point2[0][0];//最低点横坐标
 y1=point2[0][1];//最低点纵坐标
    for(int u=0;u<(count-2);u++){//计算(count-2)个三角形的面积的代数和(凹面积取负,凸面积取正)
     x2=point2[u+1][0];//三角形第2个点横坐标
  x3=point2[u+2][0];//三角形第3个点横坐标
     y2=point2[u+1][1];//三角形第2个点纵坐标
  y3=point2[u+2][1];//三角形第3个点纵坐标
  做逻辑判断此三角形是否为凹三角形,凹面积取负,凸面积取正
  if((x1==x2)&&(x1==x3)){//说明k1,k2都不存在
      continue;//结束本步循环,继续下一步
  }else if(x1==x2){//说明k1不存在
   k2=(y3-y1)/(x3-x1);//计算斜率
   if(k2<0){//k2<0说明此三角形为凹,(不考虑共线(k2=0),因为共线此时k2会不存在,会进入第一个判断)
    Sthree-=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
   }else{//为凸
                Sthree+=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
   }
  }else if(x1==x3){//说明k2不存在
      k1=(y2-y1)/(x2-x1);//计算斜率
   if(k1>0){//k1>0说明此三角形为凹,(不考虑共线(k1=0),因为共线此时k2会不存在,会进入第一个判断)
       Sthree-=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
   }else{//为凸
                Sthree+=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
   }
  }else{//说明斜率都存在
      k1=(y2-y1)/(x2-x1);//计算斜率k1
   k2=(y3-y1)/(x3-x1);//计算斜率k2
   if(k1>0&&k2<0){//为凹
       Sthree-=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
   }else if(k1<0&&k2<0){//斜率同号且小于0
    if(k1<k2){//说明为凹
        Sthree-=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
    }else{//为凸或共线
        Sthree+=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
    }
   }else if(k1>0&&k2>0){//斜率同号且大于0
    if(k1<k2){//说明为凹
        Sthree-=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
    }else{//为凸或共线
        Sthree+=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
    }
   }else{//其他为凸
       Sthree+=calculateTwoPointArea(x1,x2,x3,y1,y2,y3);//计算面积
   }
  }
 }
    cout<<"多边形的面积为:"<<Sthree<<endl;//输出总面积
}
/**
*  calculateTwoPointArea()函数,计算三角形面积,海伦公式
*  形参:float xx1,float xx2,float xx3,float yy1,float yy2,float yy3
*  返回:面积area
*/
float calculateTwoPointArea(float x1,float x2,float x3,float y1,float y2,float y3)
{
    float a,b,c,p,area;
 a=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));//计算边长1
    b=sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1));//计算边长2
    c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));//计算边长3
 p=(a+b+c)/2;
 area=sqrt(p*(p-a)*(p-b)*(p-c));//海伦公式计算面积
 return area;
}


运行结果图:



OKOKOKOK啦!!!
希望对你有用。本文章为原创,转发注明原创网址哦。
2017.5.16写。

  • 19
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值