POJ 1279 Art Gallery(半平面交)

题目链接:http://poj.org/problem?id=1279

题意:求多边形的核。

思路:枚举每条边,对于其他的点若在这条边的左侧则加入;其他的边与这条边相交则将交点加入。



 

 struct point

 {

     double x,y;

 

     point(){}

     point(double _x,double _y)

     {

         x=_x;

         y=_y;

     }

 

     void read()

     {

         RD(x,y);

     }

 

     void output()

     {

         printf("(%.2lf %.2lf)",x,y);

     }

 

     point operator+(point a)

     {

         return point(x+a.x,y+a.y);

     }

     point operator-(point a)

     {

         return point(x-a.x,y-a.y);

     }

 

     double operator*(point a)

     {

         return x*a.y-y*a.x;

     }

 

     point operator*(double t)

     {

         return point(x*t,y*t);

     }

 

     point operator/(double t)

     {

         return point(x/t,y/t);

     }

 };

 

 point a[N],b[N];

 int n,m,C;

 

 int DB(double x)

 {

     if(x>1e-10) return 1;

     if(x<-1e-10) return -1;

     return 0;

 }

 

 

 double cross(point a,point b,point t)

 {

     return point(b-a)*point(t-a);

 }

 

 double getArea(point p[],int n)

 {

     double ans=0;

     int i;

     p[n]=p[0];

     FOR0(i,n) ans+=p[i]*p[i+1];

     return ans/2;

 }

 

 point getCross(point a,point b,point p,point q)

 {

     double s1=(a-p)*(b-p);

     double s2=(b-q)*(a-q);

     double t=s1+s2;

     return (p*s2+q*s1)/(s1+s2);

 }

 

 void getCore(point a[],int n,point b[],int &m)

 {

     int i,j,x,y,u,v;

     point c[N],temp;

 

     a[n]=a[0];

     FOR0(i,n+1) c[i]=a[i];

     x=n;

     FOR0(i,n)

     {

         y=0;

         FOR0(j,x)

         {

             u=DB(cross(a[i],a[i+1],c[j]));

             v=DB(cross(a[i],a[i+1],c[j+1]));

             if(u>=0) b[y++]=c[j];

             if(u*v==-1)

             {

                 b[y++]=getCross(a[i],a[i+1],c[j],c[j+1]);

             }

         }

         b[y]=b[0];

         x=y;

         FOR0(j,y+1) c[j]=b[j];

     }

     m=y;

 }

 

 int main()

 {

     RD(C);

     while(C--)

     {

         RD(n);

         int i;

         FOR0(i,n) a[i].read();

         double s=getArea(a,n);

         if(DB(s)==-1)

         {

             FOR0(i,n/2) swap(a[i],a[n-1-i]);

         }

         getCore(a,n,b,m);

         s=getArea(b,m);

         printf("%.2lf\n",s);

     }

     return 0;

 }

  

你可能感兴趣的:(gallery)