题目大意:
给两个凸多边形,求面积交。
题目分析:
求半平面交。
代码如下:
#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;
}