poj 3335 Rotating Scoreboard - 半平面交

来源:互联网 发布:淘宝信誉升级规则 编辑:程序博客网 时间:2024/05/01 20:27
/*poj 3335 Rotating Scoreboard - 半平面交点是顺时针给出的*/#include <stdio.h>#include<math.h>const double eps=1e-8;const int N=103;struct point{    double x,y;}dian[N];inline bool mo_ee(double x,double y){double ret=x-y;if(ret<0) ret=-ret;if(ret<eps) return 1;return 0;}inline bool mo_gg(double x,double y)  {   return x > y + eps;} // x > yinline bool mo_ll(double x,double y)  {   return x < y - eps;} // x < yinline bool mo_ge(double x,double y) {   return x > y - eps;} // x >= yinline bool mo_le(double x,double y) {   return x < y + eps;} // x <= yinline double mo_xmult(point p2,point p0,point p1)//p1在p2左返回负,在右边返回正{    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}//求多边形面积double mo_area_polygon(point *dian,int n){int i;point yuan;yuan.x=yuan.y=0;double ret=0;for(i=0;i<n;++i){ret+=mo_xmult(dian[(i+1)%n],yuan,dian[i]);}return ret;}point mo_intersection(point u1,point u2,point v1,point v2){    point ret=u1;    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));    ret.x+=(u2.x-u1.x)*t;    ret.y+=(u2.y-u1.y)*t;    return ret;}///////////////////////////切割法求半平面交  point mo_banjiao_jiao[N*2];  point mo_banjiao_jiao_temp[N*2];  void mo_banjiao_cut(point *ans,point qian,point hou,int &nofdian)  {      int i,k;      for(i=k=0;i<nofdian;++i)      {          double a,b;          a=mo_xmult(hou,ans[i],qian);          b=mo_xmult(hou,ans[(i+1)%nofdian],qian);          if(mo_ge(a,0))//顺时针就是<=0          {              mo_banjiao_jiao_temp[k++]=ans[i];          }if(mo_ll(a*b,0))          {              mo_banjiao_jiao_temp[k++]=mo_intersection(qian,hou,ans[i],ans[(i+1)%nofdian]);          }      }      for(i=0;i<k;++i)      {          ans[i]=mo_banjiao_jiao_temp[i];      }      nofdian=k;  }  int mo_banjiao(point *dian,int n){int i,nofdian;double area=mo_area_polygon(dian,n);if(area<0){point temp;int zhong=n/2-1;for(i=0;i<=zhong;++i){temp=dian[i];dian[i]=dian[n-1-i];dian[n-1-i]=temp;}}nofdian=n;for(i=0;i<n;++i){mo_banjiao_jiao[i]=dian[i];}for(i=0;i<n;++i){mo_banjiao_cut(mo_banjiao_jiao,dian[i],dian[(i+1)%n],nofdian); if(nofdian==0)          {              return nofdian;          }  }return nofdian;}/////////////////////////int main(){    int t,i,n;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=0;i<n;++i)        {            scanf("%lf%lf",&dian[i].x,&dian[i].y);        }        int ret=mo_banjiao(dian,n);        if(ret==0)        {            printf("NO\n");        }else        {            printf("YES\n");        }    }    return 0;}