首页 > 代码库 > hdu3060Area2(任意多边形相交面积)

hdu3060Area2(任意多边形相交面积)

链接

多边形的面积求解是通过选取一个点(通常为原点或者多边形的第一个点)和其它边组成的三角形的有向面积。

对于两个多边形的相交面积就可以通过把多边形分解为三角形,求出三角形的有向面积递加。三角形为凸多边形,因此可以直接用凸多边形相交求面积的模板。

凸多边形相交后的部分肯定还是凸多边形,所以只需要判断哪些点是相交部分上的点,最后求下面积。

  1 #include <iostream>  2 #include<cstdio>  3 #include<cstring>  4 #include<algorithm>  5 #include<stdlib.h>  6 #include<vector>  7 #include<cmath>  8 #include<queue>  9 #include<set> 10 using namespace std; 11 #define N 510 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 struct point 18 { 19     double x,y; 20     point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写 21 }p[N],q[N]; 22 typedef point pointt; 23 pointt operator + (point a,point b) 24 { 25     return point(a.x+b.x,a.y+b.y); 26 } 27 pointt operator - (point a,point b) 28 { 29     return point(a.x-b.x,a.y-b.y); 30 } 31 int dcmp(double x) 32 { 33     if(fabs(x)<eps) return 0; 34     else return x<0?-1:1; 35 } 36 bool operator == (const point &a,const point &b) 37 { 38     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; 39 } 40 double cross(point a,point b) 41 { 42     return a.x*b.y-a.y*b.x; 43 } 44 double Polyarea(point p[],int n) 45 { 46     if(n<3) return 0; 47     double area = 0; 48     for(int i = 0 ; i < n ; i++) 49     area+=cross(p[i],p[i+1]); 50     return fabs(area)/2; 51 } 52 //double Polyarea(point p[], int n) 53 //{ 54 //    if(n < 3) return 0.0; 55 //    double s = p[0].y * (p[n - 1].x - p[1].x); 56 //    p[n] = p[0]; 57 //    for(int i = 1; i < n; ++ i) 58 //        s += p[i].y * (p[i - 1].x - p[i + 1].x); 59 //    return fabs(s * 0.5); 60 //} 61 bool intersection1(point p1, point p2, point p3, point p4, point& p)      // 直线相交 62 { 63     double a1, b1, c1, a2, b2, c2, d; 64     a1 = p1.y - p2.y; 65     b1 = p2.x - p1.x; 66     c1 = p1.x*p2.y - p2.x*p1.y; 67     a2 = p3.y - p4.y; 68     b2 = p4.x - p3.x; 69     c2 = p3.x*p4.y - p4.x*p3.y; 70     d = a1*b2 - a2*b1; 71     if (!dcmp(d))    return false; 72     p.x = (-c1*b2 + c2*b1) / d; 73     p.y = (-a1*c2 + a2*c1) / d; 74     return true; 75 } 76  77 double convexpolygon(point p[],point q[],int n,int m) 78 { 79     int i,j; 80     point ch[20],cnt[20]; 81     p[n] = p[0],q[m] = q[0]; 82     memcpy(ch,q,sizeof(point)*(m+1)); 83     int f2,g = 0 ; 84     for(i = 0 ;i < n; i++) 85     { 86         int f1 = dcmp(cross(p[i+1]-p[i],ch[0]-p[i])); 87         g = 0 ; 88         for(j = 0 ;j < m; j++,f1 = f2) 89         { 90             if(f1>=0) cnt[g++] = ch[j]; 91             f2 = dcmp(cross(p[i+1]-p[i],ch[j+1]-p[i])); 92             if((f1^f2)==-2) 93             { 94                 point pp; 95                 intersection1(p[i],p[i+1],ch[j],ch[j+1],pp); 96                 cnt[g++] = pp; 97             } 98         } 99         cnt[g] = cnt[0];100         memcpy(ch,cnt,sizeof(point)*(g+1));101         m = g;102     }103     return Polyarea(ch,g);104 }105 double solve(point p[],point q[],int n,int m)106 {107     int i,j;108     double area = 0;109     point tp[10],tq[10];110     tp[0] = p[0];tq[0] = q[0];111     for(i = 1 ;i < n-1; i++)112     {113         int k1 = dcmp(cross(p[i]-p[0],p[i+1]-p[0]));114         tp[1] = p[i],tp[2] = p[i+1];115         if(k1 < 0) swap(tp[1],tp[2]);116 117         for(j = 1 ;j < m-1 ;j++)118         {119             tq[1] = q[j],tq[2] = q[j+1];120             int k2 = dcmp(cross(q[j]-q[0],q[j+1]-q[0]));121             if(k2<0) swap(tq[1],tq[2]);122 123             area+=convexpolygon(tp,tq,3,3)*k1*k2;124         }125     }126     return Polyarea(p,n)+Polyarea(q,m)-area;127 }128 int main()129 {130     int n,m,i;131     while(scanf("%d%d",&n,&m)!=EOF)132     {133         for(i = 0; i < n ;i++)134         {135             scanf("%lf%lf",&p[i].x,&p[i].y);136         }137         for(i = 0; i < m; i++)138         {139             scanf("%lf%lf",&q[i].x,&q[i].y);140         }141         p[n] = p[0],q[m] = q[0];142         double ans = solve(p,q,n,m);143         printf("%.2f\n",ans);144     }145     return 0;146 }
View Code