Description
逆时针给出
n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图:
则相交部分的面积为5.233。
Input
第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。
Output
输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。
Sample Input
2
6
-2 0
-1 -2
1 -2
2 0
1 2
-1 2
4
0 -3
1 -1
2 2
-1 0
6
-2 0
-1 -2
1 -2
2 0
1 2
-1 2
4
0 -3
1 -1
2 2
-1 0
Sample Output
5.233
题解:
一看就发现是半平面交裸题吧。
反正蒟蒻只想到拆成每条线段求他们的半平面交。
边界打错真是日了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
#define eps 1e-13
double Maxx=1001.0;
double Minn=-1001.0;
const int N=5100;
struct node{
double x,y;
}sb[N],ss[N];int pl,cnt=0;
struct node2{
node p1,p2;
double angle;
node2(){}
node2(double x1,double y1,double x2,double y2)
{
p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2;
}
void get_angle()
{
angle=atan2(p2.y-p1.y,p2.x-p1.x);
}
}seg[N],sa[N];int st,ed;
double mulit(node p1,node p2,node p0)
{
double x1=p1.x-p0.x,y1=p1.y-p0.y;
double x2=p2.x-p0.x,y2=p2.y-p0.y;
return x1*y2-x2*y1;
}
bool satify(node x,node2 y)
{
if(mulit(x,y.p2,y.p1)<=eps) return true;return false;
}
bool cmp(node2 x,node2 y)
{
if(x.angle<y.angle) return true;
if(fabs(x.angle-y.angle)<eps&&satify(x.p1,y)==true) return true;
return false;
}
node jd(node2 x,node2 y)
{
node p1=x.p1,p2=x.p2,p3=y.p1,p4=y.p2,p;
double t1=mulit(p1,p4,p3);
double t2=mulit(p2,p4,p3);
p.x=(t1*p2.x-t2*p1.x)/(t1-t2);
p.y=(t1*p2.y-t2*p1.y)/(t1-t2);
return p;
}
void work()
{
sort(seg+1,seg+cnt+1,cmp);
int tp=1;
for(int i=2;i<=cnt;i++)
if(seg[i].angle-seg[tp].angle>eps) seg[++tp]=seg[i];
cnt=tp;
sa[1]=seg[1];sa[2]=seg[2];
st=1,ed=2;
for(int i=3;i<=cnt;i++)
{
while(st<ed&&satify(jd(sa[ed],sa[ed-1]),seg[i])==false) ed--;
while(st<ed&&satify(jd(sa[st],sa[st+1]),seg[i])==false) st++;
sa[++ed]=seg[i];
}
while(st<ed&&satify(jd(sa[ed],sa[ed-1]),seg[st])==false) ed--;
while(st<ed&&satify(jd(sa[st],sa[st+1]),seg[ed])==false) st++;
if(ed-st+1<=2){printf("0.000");return;}
pl=0;
for(int i=st;i<ed;i++) sb[++pl]=jd(sa[i],sa[i+1]);
sb[++pl]=jd(sa[ed],sa[st]);
double ans=0.000;
for(int i=3;i<=pl;i++) ans+=mulit(sb[i-1],sb[i],sb[1]);
printf("%0.3lf",fabs(ans)/2.000);
}
int n,m;
int main()
{
seg[++cnt]=node2(Minn,Minn,Maxx,Minn);seg[1].get_angle();
seg[++cnt]=node2(Maxx,Minn,Maxx,Maxx);seg[2].get_angle();
seg[++cnt]=node2(Maxx,Maxx,Minn,Maxx);seg[3].get_angle();
seg[++cnt]=node2(Minn,Maxx,Minn,Minn);seg[4].get_angle();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&m);
for(int j=1;j<=m;j++)
{
scanf("%lf%lf",&ss[j].x,&ss[j].y);
}
for(int j=1;j<m;j++)
seg[++cnt]=node2(ss[j].x,ss[j].y,ss[j+1].x,ss[j+1].y),seg[cnt].get_angle();
seg[++cnt]=node2(ss[m].x,ss[m].y,ss[1].x,ss[1].y),seg[cnt].get_angle();
}
work();
}