題目大意:
給兩個凸多邊形,求面積交。
題目分析:
求半平面交。
代碼如下:
#include <cstdio>#include <algorithm>#include <cmath>using namespace std;struct point{ double x,y; point(){} point(double x,double y):x(x),y(y){} point operator + (const point &c) const { return point(x+c.x,y+c.y); } point operator - (const point &c) const { return point(x-c.x,y-c.y); } double operator * (const point &c) const { return x*c.y-y*c.x; } point operator * (const double &c) const { return point(x*c,y*c); }}b[1000];struct line{ point p,v; double alpha; bool operator < (const line &c) const{ return alpha<c.alpha; } line(){} line(point a,point b):p(a),v(b-a){ alpha=atan2(v.y,v.x); } point operator ^ (const line &c) const { point tmp=p-c.p; double rate=(c.v*tmp)/(v*c.v); return p+v*rate; }}a[1000000],p[1000000];int tot,m,n,l,r;bool onleft(point p,line l){ point tmp=p-l.p; return l.v*tmp>=0;}void half_plane_intersection(){ sort(a+1,a+1+tot); for(int i=1;i<=tot;i++) { while(r-l>=2 && !onleft(p[r-1]^p[r-2],a[i])) r--; if(r-l>=1 && fabs(p[r-1].v*a[i].v)<=0) p[r-1]=onleft(a[i].p,p[r-1])?a[i]:p[r-1]; else p[r++]=a[i]; } for(;;) { if(r-l>=2 && !onleft(p[r-1]^p[r-2],p[l])) r--; else if(r-l>=2 && !onleft(p[l]^p[l+1],p[r-1])) l++; else break; }}int main(){ scanf("%d",&m); tot=0; for(int j=1;j<=m;j++) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&b[i].x,&b[i].y); if(i!=1) a[++tot]=line(b[i-1],b[i]); } a[++tot]=line(b[n],b[1]); } half_plane_intersection(); if(r-l<=2) printf("0.000\n"); else { int sum=0; for(int i=l+1;i<r;i++) b[++sum]=p[i-1]^p[i]; b[++sum]=p[r-1]^p[l]; double ans=0; for(int i=2;i<=sum;i++) ans+=b[i-1]*b[i]; ans+=b[sum]*b[1]; printf("%.3lf\n",ans/2.0); } return 0;}