HDU 4316 凸包 +半平面交

来源:互联网 发布:slideunlock.js 编辑:程序博客网 时间:2024/06/06 05:56

题意:给出多边形的顶点,然后在天花板有三个摄像头,找出三个摄像头的盲区。

思路:每一个摄像头 对应有一个盲区,然后把三个摄像头的盲区取交集 然后求面积就可以 这里用到了 凸包模版和半平面交模版

代码:

#include<cmath>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;struct Point{    double x,y,z;    Point(double x=0,double y=0,double z=0):x(x),y(y),z(z) {}};Point tmp[200];const double eps=1e-8;typedef Point  Vector;Vector operator -(Point A,Point B){    return Vector(A.x-B.x,A.y-B.y);}Vector operator +(Point A,Point B){    return Vector(A.x+B.x,A.y+B.y);}Vector operator *(Vector A,double p){    return Vector(A.x*p,A.y*p);}double Cross(Vector A,Vector B){    return A.x*B.y-A.y*B.x;}int n,res[1200],top;Point p[1200];bool mult(Point sp,Point ep,Point op){    return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y);}bool cmp(Point a,Point b){    if(a.y==b.y)return a.x<b.x;    return a.y<b.y;}struct Line{    Point P;    Vector v;    double ang;    Line(){}    Line(Point P,Vector v):P(P),v(v){        ang=atan2(v.y,v.x);    }    bool operator <(const Line &L)const{        return ang<L.ang;    }};bool Onleft(Line L,Point pp){    return Cross(L.v,pp-L.P)>0;}Point GetIntersection(Line a,Line b){    Vector u=a.P-b.P;    double t=Cross(b.v,u)/Cross(a.v,b.v);   // cout<<t<<endl;    return a.P+a.v*t;}void Graham(){    int len;    top=1;    sort(p,p+n,cmp);    if(n==0)return;res[0]=0;    if(n==1)return;res[1]=1;    if(n==2)return;res[2]=2;    for(int i=2;i<n;i++){        while(top&&mult(p[i],p[res[top]],p[res[top-1]]))top--;        res[++top]=i;    }    len=top;    res[++top]=n-2;    for(int i=n-3;i>=0;i--){        while(top!=len&&mult(p[i],p[res[top]],p[res[top-1]]))top--;        res[++top]=i;    }}int HalfplaneIntersection(Line* L,int n,Point *poly){    sort(L,L+n);    int ft,la;    Point *pp=new Point[n];    Line *q=new Line[n];    q[ft=la=0]=L[0];    for(int i=1;i<n;++i) {        while (ft<la&&!Onleft(L[i],pp[la-1]))            --la;        while (ft<la&&!Onleft(L[i], pp[ft])) ++ft;        q[++la]=L[i];        if(fabs(Cross(q[la].v,q[la-1].v))<eps){            la--;            if (Onleft(q[la], L[i].P))                q[la]=L[i];                    }        if(ft<la){            pp[la-1]=GetIntersection(q[la-1],q[la]);           // cout<<pp[la-1].x<<" "<<pp[la-1].y<<endl;        }    }    while (ft<la&&!Onleft(q[ft],pp[la-1])) --la;    if (la-ft<=1)        return 0;    pp[la]=GetIntersection(q[la],q[ft]);    int m=0;    for (int i=ft; i<=la; ++i) {        poly[m++]=pp[i];    }    return m;}int main(){    Point a[3];Line l[1000];    while (cin>>n) {        for (int i=0; i<n; ++i)            cin>>tmp[i].x>>tmp[i].y>>tmp[i].z;        for (int i=0; i<3; ++i)            cin>>a[i].x>>a[i].y;        int tol=0;        for (int i=0; i<3; ++i) {            for (int j=0; j<n; ++j) {                p[j].x=-100.0*(tmp[j].x-a[i].x)/(tmp[j].z-100)+a[i].x;                p[j].y=-100.0*(tmp[j].y-a[i].y)/(tmp[j].z-100)+a[i].y;            }            Graham();            //  cout<<top<<endl;            for (int j=0;j<top; ++j){              //  cout<<p[j].x<<" "<<p[j].y<<endl;                l[tol++]=Line(p[res[j]],p[res[(j+1)%top]]-p[res[j]]);            }          //  cout<<endl;        }        //  cout<<tol<<endl;        int m=HalfplaneIntersection(l, tol, tmp);        //  cout<<m<<endl;        double ans=0;        for (int i=2; i<m; ++i) {            ans+=Cross(tmp[i-1]-tmp[0],tmp[i]-tmp[0]);        }        printf("%.2f\n",ans/2.0);    }    return 0;}


原创粉丝点击