【半平面交】[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();
}
posted @ 2016-06-01 17:36  outer_form  阅读(161)  评论(0编辑  收藏  举报