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 }