poj 1279 Art Gallery - 求多边形核的面积

来源:互联网 发布:北海广电网络客服电话 编辑:程序博客网 时间:2024/05/10 18:10
/*poj 1279 Art Gallery - 求多边形核的面积*/#include<stdio.h>#include<math.h>#include <algorithm>  using namespace std;  const double eps=1e-8;struct point {double x,y;}dian[20000+10];point jiao[203];struct line  {      point s,e;      double angle;  }xian[20000+10];  int n,yong;bool mo_ee(double x,double y)  {      double ret=x-y;      if(ret<0) ret=-ret;      if(ret<eps) return 1;      return 0;  }  bool mo_gg(double x,double y)  {   return x > y + eps;} // x > y     bool mo_ll(double x,double y)  {   return x < y - eps;} // x < y     bool mo_ge(double x,double y) {   return x > y - eps;} // x >= y     bool mo_le(double x,double y) {   return x < y + eps;}     // x <= y     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;  }  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);  }  void mo_HPI_addl(point a,point b)  {  xian[yong].s=a;  xian[yong].e=b;  xian[yong].angle=atan2(b.y-a.y,b.x-a.x);  yong++;  }  //半平面交bool mo_HPI_cmp(const line& a,const line& b){if(mo_ee(a.angle,b.angle)){return mo_gg( mo_xmult(b.e,a.s,b.s),0);}else{return mo_ll(a.angle,b.angle);}}int mo_HPI_dq[20000+10];bool mo_HPI_isout(line cur,line top,line top_1){point jiao=mo_intersection(top.s,top.e,top_1.s,top_1.e);return mo_ll( mo_xmult(cur.e,jiao,cur.s),0);}int mo_HalfPlaneIntersect(line *xian,int n,point *jiao){int i,j,ret=0;sort(xian,xian+n,mo_HPI_cmp);for (i = 0, j = 0; i < n; i++){if (mo_gg(xian[i].angle,xian[j].angle)){xian[++j] = xian[i];}}n=j+1;mo_HPI_dq[0]=0;mo_HPI_dq[1]=1;int top=1,bot=0;for (i = 2; i < n; i++){        while (top > bot && mo_HPI_isout(xian[i], xian[mo_HPI_dq[top]], xian[mo_HPI_dq[top-1]])) top--;        while (top > bot && mo_HPI_isout(xian[i], xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[bot+1]])) bot++;        mo_HPI_dq[++top] = i; //当前半平面入栈}    while (top > bot && mo_HPI_isout(xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[top]], xian[mo_HPI_dq[top-1]])) top--;    while (top > bot && mo_HPI_isout(xian[mo_HPI_dq[top]], xian[mo_HPI_dq[bot]], xian[mo_HPI_dq[bot+1]])) bot++;    mo_HPI_dq[++top] = mo_HPI_dq[bot];    for (ret = 0, i = bot; i < top; i++, ret++){jiao[ret]=mo_intersection(xian[mo_HPI_dq[i+1]].s,xian[mo_HPI_dq[i+1]].e,xian[mo_HPI_dq[i]].s,xian[mo_HPI_dq[i]].e);}return ret;}//求多边形面积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;}int main(){int i,iofcase=1,t;scanf("%d",&t);while(t--){scanf("%d",&n);yong=0;for(i=0;i<n;++i){scanf("%lf%lf",&dian[i].x,&dian[i].y);}double area=mo_area_polygon(dian,n);if(area<0)//若是顺时针{for(i=0;i<n;++i){mo_HPI_addl(dian[(i+1)%n],dian[i]);}}else{for(i=0;i<n;++i){mo_HPI_addl(dian[i],dian[(i+1)%n]);}}int ret=mo_HalfPlaneIntersect(xian,n,jiao);area=mo_area_polygon(jiao,ret);if(area<0) area=-area;area=area/2;printf("%.2lf\n",area);}return 0;}

原创粉丝点击