【模板】计几多边形面积并
题目链接:https://vjudge.net/problem/HDU-3060
1 /************************************************************************* 2 > File Name: hdu30602.cpp 3 # File Name: hdu30602.cpp 4 # Author : xiaobuxie 5 # QQ : 760427180 6 # Email:760427180@qq.com 7 # Created Time: 2019年10月18日 星期五 17时25分23秒 8 ************************************************************************/ 9 10 #include<iostream> 11 #include<cstdio> 12 #include<map> 13 #include<cmath> 14 #include<cstring> 15 #include<set> 16 #include<queue> 17 #include<vector> 18 #include<algorithm> 19 using namespace std; 20 typedef long long ll; 21 #define inf 0x3f3f3f3f 22 #define eps 1e-8 23 int sgn(double x){ 24 if(fabs(x) < eps) return 0; 25 if(x<0) return -1; 26 return 1; 27 } 28 const int N = 500+8; 29 struct Point{ 30 double x,y; 31 Point(){x=y=0;} 32 Point(double a,double b){x=a,y=b;} 33 Point operator - (const Point& b)const 34 {return Point(x-b.x,y-b.y);} 35 Point operator + (const Point& b)const 36 {return Point(x+b.x,y+b.y);} 37 Point operator * (const double& b)const 38 {return Point(x*b,y*b);} 39 double dot (const Point& b)const 40 {return x*b.x+y*b.y;} 41 double cross (const Point& b,const Point& c)const 42 {return (b.x - x)*(c.y - y) - (c.x - x)*(b.y - y);} 43 double dis (const Point& b)const 44 {return sqrt( (x-b.x)*(x-b.x) + (y-b.y)*(y-b.y) );} 45 bool OnLine (const Point& st,Point& ed)const 46 {return !sgn(cross(st,ed));} 47 bool OnSeg (const Point& st,Point& ed)const 48 {return OnLine(st,ed) && (*this - ed).dot(*this - st) < eps;} 49 }pa[N],pb[N]; 50 Point LineCross(Point a,Point b,Point c,Point d){ 51 double u = a.cross(b,c), v = b.cross(a,d); 52 return Point( (c.x*v + d.x*u) / (u+v), (c.y*v + d.y*u) / (u+v)); 53 } 54 double PolygonArea(Point p[],int n){ 55 if( n < 3) return 0.0; 56 double res = 0; 57 Point o = Point(0,0); 58 p[n] = p[0]; 59 for(int i = 0;i<n;++i) res += o.cross(p[i],p[i+1]); 60 return fabs(res*0.5); 61 } 62 double CPIA(Point a[],int na,Point b[],int nb){ 63 Point p[20],tmp[20]; 64 int tn,sflag,eflag; 65 a[na] = a[0],b[nb] = b[0]; 66 memcpy(p,b,sizeof(Point)*(nb+1)); 67 for(int i = 0;i < na && nb > 2;++i){ 68 sflag = sgn( a[i].cross( a[i+1] , p[0] ) ); 69 for(int j = tn = 0; j < nb ; ++j,sflag = eflag){ 70 if( sflag >= 0 ) tmp[ tn++ ] = p[j]; 71 eflag = sgn( a[i].cross( a[i+1],p[j+1] ) ); 72 if( (sflag ^ eflag) == -2) tmp[tn++] = LineCross(a[i],a[i+1],p[j],p[j+1]); 73 } 74 memcpy(p,tmp,sizeof(Point)*tn); 75 nb = tn,p[nb] = p[0]; 76 } 77 if(nb < 3) return 0.0; 78 return PolygonArea(p,nb); 79 } 80 double SPIA(Point a[],int na,Point b[],int nb){ 81 Point t1[4],t2[4]; 82 double res = 0,num1,num2; 83 a[na] = t1[0] = a[0]; 84 b[nb] = t2[0] = b[0]; 85 for(int i = 2;i < na ; ++i){ 86 t1[1] = a[i-1],t1[2] = a[i]; 87 num1 = sgn( t1[0].cross(t1[1],t1[2]) ); 88 if(num1 < 0) swap( t1[1], t1[2]); 89 for(int j = 2; j < nb ; ++j){ 90 t2[1] = b[j - 1] , t2[2] = b[j]; 91 num2 = sgn( t2[0].cross(t2[1],t2[2]) ); 92 if(num2 < 0) swap( t2[1],t2[2] ); 93 res += CPIA(t1,3,t2,3) * num1 *num2; 94 } 95 } 96 return res; 97 } 98 int main(){ 99 int n,m; 100 while(~scanf("%d %d",&n,&m)){ 101 for(int i =0;i<n;++i) scanf("%lf %lf",&pa[i].x,&pa[i].y); 102 for(int i =0;i<m;++i) scanf("%lf %lf",&pb[i].x,&pb[i].y); 103 double ans = SPIA(pa,n,pb,m); 104 ans = PolygonArea(pa,n) + PolygonArea(pb,m) - ans; 105 printf("%.2lf\n",ans); 106 } 107 return 0; 108 }

浙公网安备 33010602011771号