概述
刚刚开通了博客,今天正好有时间来完成自己的第一篇博客文章。希望对有需要的朋友有所帮助。
今天写了一个小代码:计算任意多边形的面积。临近毕业,毕设也忙得很,还好最近完成的差不多了,就差写论文了,今天突然想到写博客是个挺有趣的东西,于是就过来写我的第一篇。
好!步入正题,不过还是先介绍一下本博客的背景。也是关于毕设的事,我的一个同学说要我帮他想想怎样计算一个滑坡面的面积。大家都知道滑坡面是一个不规则图形,所以在计算之前首先需要处理这个不规则图形,把它近似成某个多边形,然后再计算多边形的面积。当然这样做只有近似得的多边形的边数越多,精度才会越高,所以近似成的多边形可能是任意边形(三边,四边几十边不等)。下面我们就先来介绍我的思路。
图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<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;
}
最后
以上就是简单歌曲为你收集整理的C++代码计算任意多边形的面积的全部内容,希望文章能够帮你解决C++代码计算任意多边形的面积所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复