任意多边形面积—有向面积
作者:dlcms 浏览量:1487 次 发布时间:2019-10-29 04:06:26
版权声明:本文为转载文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41939839/article/details/81296550
给定多边形的顶点坐标(有序),让你来求这个多边形的面积,你会怎么做?
我们知道,任意多边形都可以分割为N个三角形,所以,如果以这为突破点,那么我们第一步就是把给定的多边形,分割为数个三角形,分别求面积,最后累加就可以了,把多边形分割为三角形的方式多种多样,在这里,我们按照如下图的方法分割:
(点如果是顺时针给出,有向面积为负,逆时针给出,有向面积为正)
对于图1而言,多边形的面积就是:
S(1->6)=S(1,2,3)+S(1,3,4)+S(1,4,5)+S(1,5,6)(对凸多边形同样适用)
如果我们不以多边形的某一点为顶点来划分三角形而是以任意一点,如下图,这个方法也是成立的:S = S_OAB + S_OBC + S_OCD + S_ODE + S_OEA。计算的时候,当我们取O点为原点时,可以简化计算。
当O点为原点时,根据向量的叉积计算公式,各个三角形的面积计算如下:
设a(x1,y1),b(x2,y2)
以下均为向量:
oa(x1,y1),ob(x2,y2)
oa X ob由线性代数叉积知识得:
=x1y2-x2y1
S_OAB = 0.5*(A_x*B_y - A_y*B_x) 【(A_x,A_y)为A点的坐标】
S_OBC = 0.5*(B_x*C_y - B_y*C_x)
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)
点如果是顺时针给出,有向面积为负,逆时针给出,有向面积为正,OAB即为O>A>B,即OA向量XOB向量
无需担心点点坐标为正还是负,正负只与点给出的顺序有关,最终结果取绝对值即可。
题目:hdu2036 http://acm.hdu.edu.cn/showproblem.php?pid=2036
//输入必须是将点按顺序输入,顺时还是逆时程序会处理的
#include<cstdio>
using namespace std;
double ans;
int n;
struct Point{
int x,y;
}a[1000000];
int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
int main(){
n=read();//共n个点
for(int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y; //a[i]=(Point){read(),read()};
for(int i=2;i<=n;i++) //取原点为辅助点
ans+=(double)(a[i].x*a[i-1].y-a[i].y*a[i-1].x)/*记得求平行四边形面积公式吗*//2.0;
//求三角形面积。全加起来就好了,因为...面积有方向(正负性),自己会消掉的
ans+=(double)(a[1].x*a[n].y-a[1].y*a[n].x)/2.0;//第1和第n个点单独处理
if(ans<0.0) ans=-ans;//顺时针与逆时针输入结果互为相反数
printf("%lf",ans);
return 0;
}
//起点为(0.0)时
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#define fre freopen("C:UsersDellDesktopin.txt", "r", stdin);
using namespace std;
struct area{
double x;double y;
};
int main(){
//fre;
int t,n;
double sum;
struct area a[109];
cin>>t;
while(t--){
sum=0.0;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i].x>>a[i].y;
for(int i=1;i<n-1;i++)
sum+=(a[i].x*a[i+1].y-a[i+1].x*a[i].y);
sum=fabs(sum/2.0); //求double绝对值用fabs,float:fabsf,int:abs
printf("%.6fn",sum);
}
return 0;
}
————————————————
版权声明:本文为CSDN博主「这是你从未听过的名字」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41939839/article/details/81296550
本文链接:https://blog.csdn.net/qq_41939839/article/details/81296550
给定多边形的顶点坐标(有序),让你来求这个多边形的面积,你会怎么做?
我们知道,任意多边形都可以分割为N个三角形,所以,如果以这为突破点,那么我们第一步就是把给定的多边形,分割为数个三角形,分别求面积,最后累加就可以了,把多边形分割为三角形的方式多种多样,在这里,我们按照如下图的方法分割:
(点如果是顺时针给出,有向面积为负,逆时针给出,有向面积为正)
对于图1而言,多边形的面积就是:
S(1->6)=S(1,2,3)+S(1,3,4)+S(1,4,5)+S(1,5,6)(对凸多边形同样适用)
如果我们不以多边形的某一点为顶点来划分三角形而是以任意一点,如下图,这个方法也是成立的:S = S_OAB + S_OBC + S_OCD + S_ODE + S_OEA。计算的时候,当我们取O点为原点时,可以简化计算。
当O点为原点时,根据向量的叉积计算公式,各个三角形的面积计算如下:
设a(x1,y1),b(x2,y2)
以下均为向量:
oa(x1,y1),ob(x2,y2)
oa X ob由线性代数叉积知识得:
=x1y2-x2y1
S_OAB = 0.5*(A_x*B_y - A_y*B_x) 【(A_x,A_y)为A点的坐标】
S_OBC = 0.5*(B_x*C_y - B_y*C_x)
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)
点如果是顺时针给出,有向面积为负,逆时针给出,有向面积为正,OAB即为O>A>B,即OA向量XOB向量
无需担心点点坐标为正还是负,正负只与点给出的顺序有关,最终结果取绝对值即可。
题目:hdu2036 http://acm.hdu.edu.cn/showproblem.php?pid=2036
//输入必须是将点按顺序输入,顺时还是逆时程序会处理的
#include<cstdio>
using namespace std;
double ans;
int n;
struct Point{
int x,y;
}a[1000000];
int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
int main(){
n=read();//共n个点
for(int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y; //a[i]=(Point){read(),read()};
for(int i=2;i<=n;i++) //取原点为辅助点
ans+=(double)(a[i].x*a[i-1].y-a[i].y*a[i-1].x)/*记得求平行四边形面积公式吗*//2.0;
//求三角形面积。全加起来就好了,因为...面积有方向(正负性),自己会消掉的
ans+=(double)(a[1].x*a[n].y-a[1].y*a[n].x)/2.0;//第1和第n个点单独处理
if(ans<0.0) ans=-ans;//顺时针与逆时针输入结果互为相反数
printf("%lf",ans);
return 0;
}
//起点为(0.0)时
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#define fre freopen("C:UsersDellDesktopin.txt", "r", stdin);
using namespace std;
struct area{
double x;double y;
};
int main(){
//fre;
int t,n;
double sum;
struct area a[109];
cin>>t;
while(t--){
sum=0.0;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i].x>>a[i].y;
for(int i=1;i<n-1;i++)
sum+=(a[i].x*a[i+1].y-a[i+1].x*a[i].y);
sum=fabs(sum/2.0); //求double绝对值用fabs,float:fabsf,int:abs
printf("%.6fn",sum);
}
return 0;
}
————————————————
版权声明:本文为CSDN博主「这是你从未听过的名字」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41939839/article/details/81296550
上一篇:测绘知识学习之控制点
下一篇:21个 MapGIS 实用小技巧
相关阅读:
- 辰汐出品高斯正算计算器 (2019-10-23)
- 白话《关于在国土空间规划中统筹划定落实三条控制线的指导意见》 (2019-11-07)
- COORD 坐标系转换 (2017-12-25)
- 这13个开源GIS软件,你了解几个? (2018-09-20)
- 辰汐出品高斯反算计算器 (2019-10-23)