【模板】计几多边形面积并

题目链接: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 }
View Code

 

posted @ 2019-10-31 15:35  小布鞋  阅读(112)  评论(0)    收藏  举报