[ECNU 1624] 求交集多边形面积

时间:2021-05-31 18:35:24
求交集多边形面积

Time Limit:1000MS Memory Limit:30000KB Total Submit:98 Accepted:42

Description 
在平面上有两给定的凸多边形,若两凸多边形相交,则它们的交集也是一个凸多边形。若两凸多边形不相交,指的是两凸多边形相离或仅限于边界点与边上相交,则相交面积为0。如图所示: 你的任务是编程给出交集多边形的面积。 [ECNU 1624] 求交集多边形面积 两给定的凸多边形按顺时针方向依次给出多边形每个顶点的坐标。

Input 
输入文件第一行为一整数M,表示第一个凸多边形的边数,以后M行分别给出了M个顶点的坐标;接着,给出第二个凸多边形的边数N,以后N行分别给出了N个顶点的坐标。

Output 
只一个数据即交集面积,保留两位小数点。

Sample Input 
4

0 0

0 1

1 1

1 0

4

-0.5 -0.5

-0.5 0.5

0.5 0.5

0.5 -0.5

Sample Output 
0.25

只适用于两个凸多边形

半平面交、不确定是不是对的、- -

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define EPS 1e-8
#define N 1010 int n;
int dq[N];
int top,bot,pn; int dump(double x)
{
if(fabs(x)<EPS) return ;
return x>?:-;
} struct Point
{
double x,y;
Point (){}
Point (double x,double y):x(x),y(y){}
Point operator - (Point p){
return Point(x-p.x,y-p.y);
}
Point operator + (Point p){
return Point(x+p.x,y+p.y);
}
Point operator * (double d){
return Point(x*d,y*d);
}
double operator ^ (Point p){
return x*p.y-y*p.x;
}
}; struct Line
{
Point s,e;
double k;
Line(){}
Line(Point s,Point e):s(s),e(e){
k=atan2(e.y-s.y,e.x-s.x);
}
Point operator & (Line l){
return s+(e-s)*(((l.e-l.s)^(l.s-s))/((l.e-l.s)^(e-s)));
}
}; Line l[N];
Point p[N]; bool HPIcmp(Line a,Line b)
{
int d=dump(a.k-b.k);
if(!d) return dump((b.s-a.s)^(b.e-a.s))>;
return d<;
} bool Judge(Line a,Line b,Line c)
{
Point p=b&c;
return dump((a.s-p)^(a.e-p))<;
} void HPI(int n)
{
int i,j;
sort(l,l+n,HPIcmp);
for(i=,j=;i<n;i++)
{
if(dump(l[i].k-l[j].k)>) l[++j]=l[i];
}
n=j+;
dq[]=;
dq[]=;
top=;
bot=;
for(i=;i<n;i++)
{
while(top>bot && Judge(l[i],l[dq[top]],l[dq[top-]])) top--;
while(top>bot && Judge(l[i],l[dq[bot]],l[dq[bot+]])) bot++;
dq[++top]=i;
}
while(top>bot && Judge(l[dq[bot]],l[dq[top]],l[dq[top-]])) top--;
while(top>bot && Judge(l[dq[top]],l[dq[bot]],l[dq[bot+]])) bot++;
dq[++top]=dq[bot];
for(pn=,i=bot;i<top;i++,pn++)
{
p[pn]=l[dq[i+]]&l[dq[i]];
}
} double GetArea()
{
double marea=;
if(pn<) return ;
for(int i=;i<pn;i++)
{
marea+=(p[i]-p[])^(p[i-]-p[]);
}
return fabs(marea)/;
} int main()
{
int n,m,tot;
while(scanf("%d%d",&n,&m)!=EOF)
{
tot=;
Point p1[N],p2[N];
for(int i=;i<n;i++) scanf("%lf%lf",&p1[i].x,&p1[i].y);
for(int i=;i<m;i++) scanf("%lf%lf",&p2[i].x,&p2[i].y);
for(int i=;i<n;i++) l[tot++]=Line(p1[i],p1[(i-+n)%n]);
for(int i=;i<m;i++) l[tot++]=Line(p2[i],p2[(i-+m)%m]);
HPI(tot);
printf("%.2f\n",GetArea());
}
return ;
}