当前位置: 首页 >> 地理信息系统 >>

任意多边形面积—有向面积

0
版权声明:本文为转载文章,遵循 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


Powered by DLKIT 开发版 © 2011-2012 DLCMS.NET Inc.
Copyright © 2017-2023 南充辰汐科技有限公司

住所:南充市顺庆区油院路30号南充高新孵化园内

联系人:刘义君

联系电话:18781755505(微信同号)

QQ:23424830

Email : 23424830@QQ.com