【半平面交】[POJ2451]Uyuw's Concert
题目大意
在一个10000*10000的区域内,求半平面交的面积。
分析
半平面交模板题。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 20000
#define EPS 1e-8
int n,m;
void Read(int &x){
char c;
while(c=getchar(),c!=EOF)
if(c>='0'&&c<='9'){
x=c-'0';
while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';
ungetc(c,stdin);
return;
}
}
struct point{
double x,y;
point(double x=0,double y=0):x(x),y(y){
}
point operator+(const point &a)const{
return point(x+a.x,y+a.y);
}
point operator-(const point &a)const{
return point(x-a.x,y-a.y);
}
point operator*(const point &a)const{
return point(x*a.x-y*a.y,x*a.y+y*a.x);
}
void operator-=(const point&b){
*this=*this-b;
}
}poly[MAXN+10];
struct Line{
point p,v;
double ang;
Line(){
}
Line(const point &p,const point &v):p(p),v(v){
ang=atan2(v.y,v.x);
}
bool operator<(const Line &b)const{
return ang<b.ang;
}
}L[MAXN+10];
double cross(point a,point b){
return a.x*b.y-a.y*b.x;
}
point Get_intersection(const Line &a,const Line &b){
point p=a.p-b.p;
double t=cross(b.v,p)/cross(a.v,b.v);
return a.p+a.v*t;
}
bool Onleft(const Line &a,const point &b){
return cross(a.v,b-a.p)>EPS;
}
Line q[MAXN+10];
point p[MAXN+10];
int halfplaneintersection(Line *L,point *poly){
int fr,bk,i;
sort(L+1,L+n+1);
q[fr=bk=0]=L[1];
for(i=2;i<=n;i++){
while(fr<bk&&!Onleft(L[i],p[bk-1]))
bk--;
while(fr<bk&&!Onleft(L[i],p[fr]))
fr++;
q[++bk]=L[i];
if(fabs(cross(q[bk-1].v,q[bk].v))<EPS){
bk--;
if(Onleft(q[bk],L[i].p))
q[bk]=L[i];
}
if(fr<bk)
p[bk-1]=Get_intersection(q[bk],q[bk-1]);
}
while(fr<bk&&!Onleft(q[fr],p[bk-1]))
bk--;
if(bk-fr<=1)
return 0;
p[bk]=Get_intersection(q[fr],q[bk]);
for(i=fr;i<=bk;i++)
poly[++m]=p[i];
return m;
}
void read(){
Read(n);
double x1,x2,y1,y2;
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
L[i]=Line(point(x1,y1),point(x2-x1,y2-y1));
}
L[++n]=Line(point(0,10000),point(-10000,0));
L[++n]=Line(point(0,0),point(10000,0));
L[++n]=Line(point(0,0),point(0,-10000));
L[++n]=Line(point(10000,0),point(0,10000));
}
double ans;
void print(){
int i;
poly[m+1]=poly[1];
for(i=1;i<=m;i++)
ans+=cross(poly[i],poly[i+1])/2;
printf("%.1lf",ans);
}
int main()
{
read();
halfplaneintersection(L,poly);
print();
}