半平面交 模板 bzoj2618 【Cqoi2006】凸多邊形

題目大意:
給兩個凸多邊形,求面積交。

題目分析:
求半平面交。

代碼如下:

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章