hdu3982 直线切多边形

题意:有一块蛋糕,上面有一颗cherry。用刀子切n次,求切完之后有cherry的那部分的面积

My solution:

先做一个大矩形,使cake内切于这个大矩形。如图:

然后不断切这个大矩形,每次切割的时候保留与cherry同侧的那部分。最后剩下的就是一个多边形。求该多边形与圆的面积交即可。

在切割的时候如何保证留下来的是与cherry同侧的部分呢?很简单

方法不难,但是一直WA= =。遇到了个奇怪的问题:

对于这组数据:

3

5 2
-5 0 5 3
-5 0 5 -3
0 0
5 2
-5 0 5 3
-5 0 5 -3
0 4.9
5 2
-5 0 5 3
-5 0 5 -3
0 -4.9

画出来图是这样的:

标程输出结果:

My solution:

可是标程明显不对啊尼玛!加起来都超过1了是什么鬼!

思考ing.........

附WA code:

   1 #include<vector>
   2 #include<list>
   3 #include<map>
   4 #include<set>
   5 #include<deque>
   6 #include<queue>
   7 #include<stack>
   8 #include<bitset>
   9 #include<algorithm>
  10 #include<functional>
  11 #include<numeric>
  12 #include<utility>
  13 #include<iostream>
  14 #include<sstream>
  15 #include<iomanip>
  16 #include<cstdio>
  17 #include<cmath>
  18 #include<cstdlib>
  19 #include<cctype>
  20 #include<string>
  21 #include<cstring>
  22 #include<cstdio>
  23 #include<cmath>
  24 #include<cstdlib>
  25 #include<ctime>
  26 #include<climits>
  27 #include<complex>
  28 #define mp make_pair
  29 #define pb push_back
  30 using namespace std;
  31 const double eps=1e-6;
  32 const double pi=acos(-1.0);
  33 const double inf=1e20;
  34 const int maxp=11000;
  35
  36 int sgn(double x)
  37 {
  38     if (fabs(x)<eps)    return 0;
  39     if (x<0)    return -1;
  40         else return 1;
  41 }
  42
  43 int dblcmp(double d)
  44 {
  45     if (fabs(d)<eps)return 0;
  46     return d>eps?1:-1;
  47 }
  48
  49 inline double sqr(double x){return x*x;}
  50
  51 struct point
  52 {
  53     double x,y;
  54     point(){}
  55     point(double _x,double _y):
  56     x(_x),y(_y){};
  57     void input()
  58     {
  59         scanf("%lf%lf",&x,&y);
  60     }
  61     void output()
  62     {
  63         printf("%.2f %.2f\n",x,y);
  64     }
  65     bool operator==(point a)const
  66     {
  67         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
  68     }
  69     bool operator<(point a)const
  70     {
  71         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
  72     }
  73
  74     point operator +(const point &b)const
  75     {
  76         return point(x+b.x,y+b.y);
  77     }
  78     point operator -(const point &b)const
  79     {
  80         return point(x-b.x,y-b.y);
  81     }
  82     point operator *(const double &k)const
  83     {
  84         return point(x*k,y*k);
  85     }
  86     point operator /(const double &k)const
  87     {
  88         return point(x/k,y/k);
  89     }
  90     double operator *(const point &b)const
  91     {
  92         return x*b.x+y*b.y;
  93     }
  94     double operator ^(const point &b)const
  95     {
  96         return x*b.y-y*b.x;
  97     }
  98
  99     double len()
 100     {
 101         return hypot(x,y);
 102     }
 103     double len2()
 104     {
 105         return x*x+y*y;
 106     }
 107     double distance(point p)
 108     {
 109         return hypot(x-p.x,y-p.y);
 110     }
 111     point add(point p)
 112     {
 113         return point(x+p.x,y+p.y);
 114     }
 115     point sub(point p)
 116     {
 117         return point(x-p.x,y-p.y);
 118     }
 119     point mul(double b)
 120     {
 121         return point(x*b,y*b);
 122     }
 123     point div(double b)
 124     {
 125         return point(x/b,y/b);
 126     }
 127     double dot(point p)
 128     {
 129         return x*p.x+y*p.y;
 130     }
 131     double det(point p)
 132     {
 133         return x*p.y-y*p.x;
 134     }
 135     double rad(point a,point b)
 136     {
 137         point p=*this;
 138         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
 139     }
 140     point trunc(double r)
 141     {
 142         double l=len();
 143         if (!dblcmp(l))return *this;
 144         r/=l;
 145         return point(x*r,y*r);
 146     }
 147     point rotleft()
 148     {
 149         return point(-y,x);
 150     }
 151     point rotright()
 152     {
 153         return point(y,-x);
 154     }
 155     point rotate(point p,double angle)//绕点p逆时针旋转angle角度
 156     {
 157         point v=this->sub(p);
 158         double c=cos(angle),s=sin(angle);
 159         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
 160     }
 161 };
 162
 163 struct line
 164 {
 165     point a,b;
 166     line(){}
 167     line(point _a,point _b)
 168     {
 169         a=_a;
 170         b=_b;
 171     }
 172     bool operator==(line v)
 173     {
 174         return (a==v.a)&&(b==v.b);
 175     }
 176     //倾斜角angle
 177     line(point p,double angle)
 178     {
 179         a=p;
 180         if (dblcmp(angle-pi/2)==0)
 181         {
 182             b=a.add(point(0,1));
 183         }
 184         else
 185         {
 186             b=a.add(point(1,tan(angle)));
 187         }
 188     }
 189     //ax+by+c=0
 190     line(double _a,double _b,double _c)
 191     {
 192         if (dblcmp(_a)==0)
 193         {
 194             a=point(0,-_c/_b);
 195             b=point(1,-_c/_b);
 196         }
 197         else if (dblcmp(_b)==0)
 198         {
 199             a=point(-_c/_a,0);
 200             b=point(-_c/_a,1);
 201         }
 202         else
 203         {
 204             a=point(0,-_c/_b);
 205             b=point(1,(-_c-_a)/_b);
 206         }
 207     }
 208     void input()
 209     {
 210         a.input();
 211         b.input();
 212     }
 213     void adjust()
 214     {
 215         if (b<a)swap(a,b);
 216     }
 217     double length()
 218     {
 219         return a.distance(b);
 220     }
 221     double angle()//直线倾斜角 0<=angle<180
 222     {
 223         double k=atan2(b.y-a.y,b.x-a.x);
 224         if (dblcmp(k)<0)k+=pi;
 225         if (dblcmp(k-pi)==0)k-=pi;
 226         return k;
 227     }
 228     //点和线段关系
 229     //1 在逆时针
 230     //2 在顺时针
 231     //3 平行
 232     int relation(point p)
 233     {
 234         int c=dblcmp(p.sub(a).det(b.sub(a)));
 235         if (c<0)return 1;
 236         if (c>0)return 2;
 237         return 3;
 238     }
 239     bool pointonseg(point p)
 240     {
 241         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
 242     }
 243     bool parallel(line v)
 244     {
 245         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
 246     }
 247     //2 规范相交
 248     //1 非规范相交
 249     //0 不相交
 250     int segcrossseg(line v)
 251     {
 252         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
 253         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
 254         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
 255         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
 256         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
 257         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
 258                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
 259                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
 260                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
 261     }
 262     int linecrossseg(line v)//*this seg v line
 263     {
 264         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
 265         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
 266         if ((d1^d2)==-2)return 2;
 267         return (d1==0||d2==0);
 268     }
 269     //0 平行
 270     //1 重合
 271     //2 相交
 272     int linecrossline(line v)
 273     {
 274         if ((*this).parallel(v))
 275         {
 276             return v.relation(a)==3;
 277         }
 278         return 2;
 279     }
 280     point crosspoint(line v)
 281     {
 282         double a1=v.b.sub(v.a).det(a.sub(v.a));
 283         double a2=v.b.sub(v.a).det(b.sub(v.a));
 284         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
 285     }
 286     double dispointtoline(point p)
 287     {
 288         return fabs(p.sub(a).det(b.sub(a)))/length();
 289     }
 290     double dispointtoseg(point p)
 291     {
 292         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
 293         {
 294             return min(p.distance(a),p.distance(b));
 295         }
 296         return dispointtoline(p);
 297     }
 298     point lineprog(point p)
 299     {
 300         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
 301     }
 302     point symmetrypoint(point p)
 303     {
 304         point q=lineprog(p);
 305         return point(2*q.x-p.x,2*q.y-p.y);
 306     }
 307 };
 308
 309 struct Vector:public point
 310 {
 311     Vector(){}
 312     Vector(double a,double b)
 313     {
 314         x=a;    y=b;
 315     }
 316     Vector(point _a,point _b)   //a->b
 317     {
 318         double dx=_b.x-_a.x;
 319         double dy=_b.y-_a.y;
 320         x=dx;   y=dy;
 321     }
 322     Vector(line v)
 323     {
 324         double dx=v.b.x-v.a.x;
 325         double dy=v.b.y-v.a.y;
 326         x=dx;   y=dy;
 327     }
 328     double length()
 329     {
 330         return (sqrt(x*x+y*y));
 331     }
 332     Vector Normal()
 333     {
 334         double L=sqrt(x*x+y*y);
 335         Vector Vans=Vector(-y/L,x/L);
 336         return Vans;
 337     }
 338 };
 339
 340 struct circle
 341 {
 342     point p;
 343     double r;
 344     circle(){}
 345     circle(point _p,double _r):
 346     p(_p),r(_r){};
 347     circle(double x,double y,double _r):
 348     p(point(x,y)),r(_r){};
 349     circle(point a,point b,point c)//三角形的外接圆
 350     {
 351         p=line(a.add(b).div(2),a.add(b).div(2).add(b.sub(a).rotleft())).crosspoint(line(c.add(b).div(2),c.add(b).div(2).add(b.sub(c).rotleft())));
 352         r=p.distance(a);
 353     }
 354     circle(point a,point b,point c,bool t)//三角形的内切圆
 355     {
 356         line u,v;
 357         double m=atan2(b.y-a.y,b.x-a.x),n=atan2(c.y-a.y,c.x-a.x);
 358         u.a=a;
 359         u.b=u.a.add(point(cos((n+m)/2),sin((n+m)/2)));
 360         v.a=b;
 361         m=atan2(a.y-b.y,a.x-b.x),n=atan2(c.y-b.y,c.x-b.x);
 362         v.b=v.a.add(point(cos((n+m)/2),sin((n+m)/2)));
 363         p=u.crosspoint(v);
 364         r=line(a,b).dispointtoseg(p);
 365     }
 366     void input()
 367     {
 368         p.input();
 369         scanf("%lf",&r);
 370     }
 371     void output()
 372     {
 373         printf("%.2lf %.2lf %.2lf\n",p.x,p.y,r);
 374     }
 375     bool operator==(circle v)
 376     {
 377         return ((p==v.p)&&dblcmp(r-v.r)==0);
 378     }
 379     bool operator<(circle v)const
 380     {
 381         return ((p<v.p)||(p==v.p)&&dblcmp(r-v.r)<0);
 382     }
 383     double area()
 384     {
 385         return pi*sqr(r);
 386     }
 387     double circumference()
 388     {
 389         return 2*pi*r;
 390     }
 391     //0 圆外
 392     //1 圆上
 393     //2 圆内
 394     int relation(point b)
 395     {
 396         double dst=b.distance(p);
 397         if (dblcmp(dst-r)<0)return 2;
 398         if (dblcmp(dst-r)==0)return 1;
 399         return 0;
 400     }
 401     int relationseg(line v)
 402     {
 403         double dst=v.dispointtoseg(p);
 404         if (dblcmp(dst-r)<0)return 2;
 405         if (dblcmp(dst-r)==0)return 1;
 406         return 0;
 407     }
 408     int relationline(line v)
 409     {
 410         double dst=v.dispointtoline(p);
 411         if (dblcmp(dst-r)<0)return 2;
 412         if (dblcmp(dst-r)==0)return 1;
 413         return 0;
 414     }
 415     //过a b两点 半径r的两个圆
 416     int getcircle(point a,point b,double r,circle&c1,circle&c2)
 417     {
 418         circle x(a,r),y(b,r);
 419         int t=x.pointcrosscircle(y,c1.p,c2.p);
 420         if (!t)return 0;
 421         c1.r=c2.r=r;
 422         return t;
 423     }
 424     //与直线u相切 过点q 半径r1的圆
 425     int getcircle(line u,point q,double r1,circle &c1,circle &c2)
 426     {
 427         double dis=u.dispointtoline(q);
 428         if (dblcmp(dis-r1*2)>0)return 0;
 429         if (dblcmp(dis)==0)
 430         {
 431             c1.p=q.add(u.b.sub(u.a).rotleft().trunc(r1));
 432             c2.p=q.add(u.b.sub(u.a).rotright().trunc(r1));
 433             c1.r=c2.r=r1;
 434             return 2;
 435         }
 436         line u1=line(u.a.add(u.b.sub(u.a).rotleft().trunc(r1)),u.b.add(u.b.sub(u.a).rotleft().trunc(r1)));
 437         line u2=line(u.a.add(u.b.sub(u.a).rotright().trunc(r1)),u.b.add(u.b.sub(u.a).rotright().trunc(r1)));
 438         circle cc=circle(q,r1);
 439         point p1,p2;
 440         if (!cc.pointcrossline(u1,p1,p2))cc.pointcrossline(u2,p1,p2);
 441         c1=circle(p1,r1);
 442         if (p1==p2)
 443         {
 444             c2=c1;return 1;
 445         }
 446         c2=circle(p2,r1);
 447         return 2;
 448     }
 449     //同时与直线u,v相切 半径r1的圆
 450     int getcircle(line u,line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4)
 451     {
 452         if (u.parallel(v))return 0;
 453         line u1=line(u.a.add(u.b.sub(u.a).rotleft().trunc(r1)),u.b.add(u.b.sub(u.a).rotleft().trunc(r1)));
 454         line u2=line(u.a.add(u.b.sub(u.a).rotright().trunc(r1)),u.b.add(u.b.sub(u.a).rotright().trunc(r1)));
 455         line v1=line(v.a.add(v.b.sub(v.a).rotleft().trunc(r1)),v.b.add(v.b.sub(v.a).rotleft().trunc(r1)));
 456         line v2=line(v.a.add(v.b.sub(v.a).rotright().trunc(r1)),v.b.add(v.b.sub(v.a).rotright().trunc(r1)));
 457         c1.r=c2.r=c3.r=c4.r=r1;
 458         c1.p=u1.crosspoint(v1);
 459         c2.p=u1.crosspoint(v2);
 460         c3.p=u2.crosspoint(v1);
 461         c4.p=u2.crosspoint(v2);
 462         return 4;
 463     }
 464     //同时与不相交圆cx,cy相切 半径为r1的圆
 465     int getcircle(circle cx,circle cy,double r1,circle&c1,circle&c2)
 466     {
 467         circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);
 468         int t=x.pointcrosscircle(y,c1.p,c2.p);
 469         if (!t)return 0;
 470         c1.r=c2.r=r1;
 471         return t;
 472     }
 473     int pointcrossline(line v,point &p1,point &p2)//求与线段交要先判断relationseg
 474     {
 475         if (!(*this).relationline(v))return 0;
 476         point a=v.lineprog(p);
 477         double d=v.dispointtoline(p);
 478         d=sqrt(r*r-d*d);
 479         if (dblcmp(d)==0)
 480         {
 481             p1=a;
 482             p2=a;
 483             return 1;
 484         }
 485         p1=a.sub(v.b.sub(v.a).trunc(d));
 486         p2=a.add(v.b.sub(v.a).trunc(d));
 487         return 2;
 488     }
 489     //5 相离
 490     //4 外切
 491     //3 相交
 492     //2 内切
 493     //1 内含
 494     int relationcircle(circle v)
 495     {
 496         double d=p.distance(v.p);
 497         if (dblcmp(d-r-v.r)>0)return 5;
 498         if (dblcmp(d-r-v.r)==0)return 4;
 499         double l=fabs(r-v.r);
 500         if (dblcmp(d-r-v.r)<0&&dblcmp(d-l)>0)return 3;
 501         if (dblcmp(d-l)==0)return 2;
 502         if (dblcmp(d-l)<0)return 1;
 503     }
 504     int pointcrosscircle(circle v,point &p1,point &p2)
 505     {
 506         int rel=relationcircle(v);
 507         if (rel==1||rel==5)return 0;
 508         double d=p.distance(v.p);
 509         double l=(d+(sqr(r)-sqr(v.r))/d)/2;
 510         double h=sqrt(sqr(r)-sqr(l));
 511         p1=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotleft().trunc(h)));
 512         p2=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotright().trunc(h)));
 513         if (rel==2||rel==4)
 514         {
 515             return 1;
 516         }
 517         return 2;
 518     }
 519     //过一点做圆的切线 (先判断点和圆关系)
 520     int tangentline(point q,line &u,line &v)
 521     {
 522         int x=relation(q);
 523         if (x==2)return 0;
 524         if (x==1)
 525         {
 526             u=line(q,q.add(q.sub(p).rotleft()));
 527             v=u;
 528             return 1;
 529         }
 530         double d=p.distance(q);
 531         double l=sqr(r)/d;
 532         double h=sqrt(sqr(r)-sqr(l));
 533         u=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotleft().trunc(h))));
 534         v=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotright().trunc(h))));
 535         return 2;
 536     }
 537     double areacircle(circle v)
 538     {
 539         int rel=relationcircle(v);
 540         if (rel>=4)return 0.0;
 541         if (rel<=2)return min(area(),v.area());
 542         double d=p.distance(v.p);
 543         double hf=(r+v.r+d)/2.0;
 544         double ss=2*sqrt(hf*(hf-r)*(hf-v.r)*(hf-d));
 545         double a1=acos((r*r+d*d-v.r*v.r)/(2.0*r*d));
 546         a1=a1*r*r;
 547         double a2=acos((v.r*v.r+d*d-r*r)/(2.0*v.r*d));
 548         a2=a2*v.r*v.r;
 549         return a1+a2-ss;
 550     }
 551     double areatriangle(point a,point b)
 552     {
 553         if (dblcmp(p.sub(a).det(p.sub(b))==0))return 0.0;
 554         point q[5];
 555         int len=0;
 556         q[len++]=a;
 557         line l(a,b);
 558         point p1,p2;
 559         if (pointcrossline(l,q[1],q[2])==2)
 560         {
 561             if (dblcmp(a.sub(q[1]).dot(b.sub(q[1])))<0)q[len++]=q[1];
 562             if (dblcmp(a.sub(q[2]).dot(b.sub(q[2])))<0)q[len++]=q[2];
 563         }
 564         q[len++]=b;
 565         if (len==4&&(dblcmp(q[0].sub(q[1]).dot(q[2].sub(q[1])))>0))swap(q[1],q[2]);
 566         double res=0;
 567         int i;
 568         for (i=0;i<len-1;i++)
 569         {
 570             if (relation(q[i])==0||relation(q[i+1])==0)
 571             {
 572                 double arg=p.rad(q[i],q[i+1]);
 573                 res+=r*r*arg/2.0;
 574             }
 575             else
 576             {
 577                 res+=fabs(q[i].sub(p).det(q[i+1].sub(p))/2.0);
 578             }
 579         }
 580         return res;
 581     }
 582 };
 583
 584 struct polygon
 585 {
 586     int n;
 587     point p[maxp];
 588     line l[maxp];
 589     void input(int X)
 590     {
 591         n=X;
 592         for (int i=0;i<n;i++)
 593         {
 594             p[i].input();
 595         }
 596     }
 597     void add(point q)
 598     {
 599         p[n++]=q;
 600     }
 601     void getline()
 602     {
 603         for (int i=0;i<n;i++)
 604         {
 605             l[i]=line(p[i],p[(i+1)%n]);
 606         }
 607     }
 608     struct cmp
 609     {
 610         point p;
 611         cmp(const point &p0){p=p0;}
 612         bool operator()(const point &aa,const point &bb)
 613         {
 614             point a=aa,b=bb;
 615             int d=dblcmp(a.sub(p).det(b.sub(p)));
 616             if (d==0)
 617             {
 618                 return dblcmp(a.distance(p)-b.distance(p))<0;
 619             }
 620             return d>0;
 621         }
 622     };
 623     void norm()
 624     {
 625         point mi=p[0];
 626         for (int i=1;i<n;i++)mi=min(mi,p[i]);
 627         sort(p,p+n,cmp(mi));
 628     }
 629     void getconvex(polygon &convex)
 630     {
 631         int i,j,k;
 632         sort(p,p+n);
 633         convex.n=n;
 634         for (i=0;i<min(n,2);i++)
 635         {
 636             convex.p[i]=p[i];
 637         }
 638         if (n<=2)return;
 639         int &top=convex.n;
 640         top=1;
 641         for (i=2;i<n;i++)
 642         {
 643             while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
 644                 top--;
 645             convex.p[++top]=p[i];
 646         }
 647         int temp=top;
 648         convex.p[++top]=p[n-2];
 649         for (i=n-3;i>=0;i--)
 650         {
 651             while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
 652                 top--;
 653             convex.p[++top]=p[i];
 654         }
 655     }
 656
 657     //ADD
 658     //a new oonvex algorithm
 659 /*  void Graham(polygon &convex)
 660     {
 661         norm();
 662         int &top=convex.n;
 663         top=0;
 664         if (n==1)
 665         {
 666             top=1;
 667             convex.p[0]=p[0];
 668             return;
 669         }
 670         if (n==2)
 671         {
 672             top=2;
 673             convex.p[0]=p[0];
 674             convex.p[1]=p[1];
 675             if (convex.p[0]==convex.p[1])   top--;
 676             return;
 677         }
 678         convex.p[0]=p[0];
 679         convex.p[1]=p[1];
 680         top=2;
 681         for (int i=2;i<n;i++)
 682         {
 683             while (top>1 && sgn((convex.p[top-1]-convex.p[top-2])^(p[i]-convex.p[top-2]))<=0)
 684                 top--;
 685             convex.p[top++]=p[i];
 686         }
 687         if (convex.n==2 && (convex.p[0]==convex.p[1]))  convex.n--;
 688     }
 689 */
 690     bool isconvex()
 691     {
 692         bool s[3];
 693         memset(s,0,sizeof(s));
 694         int i,j,k;
 695         for (i=0;i<n;i++)
 696         {
 697             j=(i+1)%n;
 698             k=(j+1)%n;
 699             s[dblcmp(p[j].sub(p[i]).det(p[k].sub(p[i])))+1]=1;
 700             if (s[0]&&s[2])return 0;
 701         }
 702         return 1;
 703     }
 704     //3 点上
 705     //2 边上
 706     //1 内部
 707     //0 外部
 708     int relationpoint(point q)
 709     {
 710         int i,j;
 711         for (i=0;i<n;i++)
 712         {
 713             if (p[i]==q)return 3;
 714         }
 715         getline();
 716         for (i=0;i<n;i++)
 717         {
 718             if (l[i].pointonseg(q))return 2;
 719         }
 720         int cnt=0;
 721         for (i=0;i<n;i++)
 722         {
 723             j=(i+1)%n;
 724             int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
 725             int u=dblcmp(p[i].y-q.y);
 726             int v=dblcmp(p[j].y-q.y);
 727             if (k>0&&u<0&&v>=0)cnt++;
 728             if (k<0&&v<0&&u>=0)cnt--;
 729         }
 730         return cnt!=0;
 731     }
 732     //1 在多边形内长度为正
 733     //2 相交或与边平行
 734     //0 无任何交点
 735     int relationline(line u)
 736     {
 737         int i,j,k=0;
 738         getline();
 739         for (i=0;i<n;i++)
 740         {
 741             if (l[i].segcrossseg(u)==2)return 1;
 742             if (l[i].segcrossseg(u)==1)k=1;
 743         }
 744         if (!k)return 0;
 745         vector<point>vp;
 746         for (i=0;i<n;i++)
 747         {
 748             if (l[i].segcrossseg(u))
 749             {
 750                 if (l[i].parallel(u))
 751                 {
 752                     vp.pb(u.a);
 753                     vp.pb(u.b);
 754                     vp.pb(l[i].a);
 755                     vp.pb(l[i].b);
 756                     continue;
 757                 }
 758                 vp.pb(l[i].crosspoint(u));
 759             }
 760         }
 761         sort(vp.begin(),vp.end());
 762         int sz=vp.size();
 763         for (i=0;i<sz-1;i++)
 764         {
 765             point mid=vp[i].add(vp[i+1]).div(2);
 766             if (relationpoint(mid)==1)return 1;
 767         }
 768         return 2;
 769     }
 770     //直线u切割凸多边形左侧
 771     //注意直线方向
 772     void convexcut(line u,polygon &po)
 773     {
 774         int i,j,k;
 775         int &top=po.n;
 776         top=0;
 777         for (i=0;i<n;i++)
 778         {
 779             int d1=dblcmp(p[i].sub(u.a).det(u.b.sub(u.a)));
 780             int d2=dblcmp(p[(i+1)%n].sub(u.a).det(u.b.sub(u.a)));
 781             if (d1>=0)po.p[top++]=p[i];
 782             if (d1*d2<0)po.p[top++]=u.crosspoint(line(p[i],p[(i+1)%n]));
 783         }
 784     }
 785     double getcircumference()
 786     {
 787         double sum=0;
 788         int i;
 789         for (i=0;i<n;i++)
 790         {
 791             sum+=p[i].distance(p[(i+1)%n]);
 792         }
 793         return sum;
 794     }
 795     double getarea()
 796     {
 797         double sum=0;
 798         int i;
 799         for (i=0;i<n;i++)
 800         {
 801             sum+=p[i].det(p[(i+1)%n]);
 802         }
 803         return fabs(sum)/2;
 804     }
 805     bool getdir()//1代表逆时针 0代表顺时针
 806     {
 807         double sum=0;
 808         int i;
 809         for (i=0;i<n;i++)
 810         {
 811             sum+=p[i].det(p[(i+1)%n]);
 812         }
 813         if (dblcmp(sum)>0)return 1;
 814         return 0;
 815     }
 816     point getbarycentre()
 817     {
 818         point ret(0,0);
 819         double area=0;
 820         int i;
 821         for (i=1;i<n-1;i++)
 822         {
 823             double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0]));
 824             if (dblcmp(tmp)==0)continue;
 825             area+=tmp;
 826             ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp;
 827             ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp;
 828         }
 829         if (dblcmp(area))ret=ret.div(area);
 830         return ret;
 831     }
 832     /*      shen me gui !
 833     double areaintersection(polygon po)
 834     {
 835     }
 836     double areaunion(polygon po)
 837     {
 838         return getarea()+po.getarea()-areaintersection(po);
 839     }
 840     */
 841     double areacircle(circle c)
 842     {
 843         int i,j,k,l,m;
 844         double ans=0;
 845         for (i=0;i<n;i++)
 846         {
 847             int j=(i+1)%n;
 848             if (dblcmp(p[j].sub(c.p).det(p[i].sub(c.p)))>=0)
 849             {
 850                 ans+=c.areatriangle(p[i],p[j]);
 851             }
 852             else
 853             {
 854                 ans-=c.areatriangle(p[i],p[j]);
 855             }
 856         }
 857         return fabs(ans);
 858     }
 859     //多边形和圆关系
 860     //0 一部分在圆外
 861     //1 与圆某条边相切
 862     //2 完全在圆内
 863     int relationcircle(circle c)
 864     {
 865         getline();
 866         int i,x=2;
 867         if (relationpoint(c.p)!=1)return 0;
 868         for (i=0;i<n;i++)
 869         {
 870             if (c.relationseg(l[i])==2)return 0;
 871             if (c.relationseg(l[i])==1)x=1;
 872         }
 873         return x;
 874     }
 875     void find(int st,point tri[],circle &c)
 876     {
 877         if (!st)
 878         {
 879             c=circle(point(0,0),-2);
 880         }
 881         if (st==1)
 882         {
 883             c=circle(tri[0],0);
 884         }
 885         if (st==2)
 886         {
 887             c=circle(tri[0].add(tri[1]).div(2),tri[0].distance(tri[1])/2.0);
 888         }
 889         if (st==3)
 890         {
 891             c=circle(tri[0],tri[1],tri[2]);
 892         }
 893     }
 894     void solve(int cur,int st,point tri[],circle &c)
 895     {
 896         find(st,tri,c);
 897         if (st==3)return;
 898         int i;
 899         for (i=0;i<cur;i++)
 900         {
 901             if (dblcmp(p[i].distance(c.p)-c.r)>0)
 902             {
 903                 tri[st]=p[i];
 904                 solve(i,st+1,tri,c);
 905             }
 906         }
 907     }
 908     circle mincircle()//点集最小圆覆盖
 909     {
 910         random_shuffle(p,p+n);
 911         point tri[4];
 912         circle c;
 913         solve(n,0,tri,c);
 914         return c;
 915     }
 916     int circlecover(double r)//单位圆覆盖
 917     {
 918         int ans=0,i,j;
 919         vector<pair<double,int> >v;
 920         for (i=0;i<n;i++)
 921         {
 922             v.clear();
 923             for (j=0;j<n;j++)if (i!=j)
 924             {
 925                 point q=p[i].sub(p[j]);
 926                 double d=q.len();
 927                 if (dblcmp(d-2*r)<=0)
 928                 {
 929                     double arg=atan2(q.y,q.x);
 930                     if (dblcmp(arg)<0)arg+=2*pi;
 931                     double t=acos(d/(2*r));
 932                     v.push_back(make_pair(arg-t+2*pi,-1));
 933                     v.push_back(make_pair(arg+t+2*pi,1));
 934                 }
 935             }
 936             sort(v.begin(),v.end());
 937             int cur=0;
 938             for (j=0;j<v.size();j++)
 939             {
 940                 if (v[j].second==-1)++cur;
 941                 else --cur;
 942                 ans=max(ans,cur);
 943             }
 944         }
 945         return ans+1;
 946     }
 947     int pointinpolygon(point q)//点在凸多边形内部的判定
 948     {
 949         if (getdir())reverse(p,p+n);
 950         if (dblcmp(q.sub(p[0]).det(p[n-1].sub(p[0])))==0)
 951         {
 952             if (line(p[n-1],p[0]).pointonseg(q))return n-1;
 953             return -1;
 954         }
 955         int low=1,high=n-2,mid;
 956         while (low<=high)
 957         {
 958             mid=(low+high)>>1;
 959             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>=0&&dblcmp(q.sub(p[0]).det(p[mid+1].sub(p[0])))<0)
 960             {
 961                 polygon c;
 962                 c.p[0]=p[mid];
 963                 c.p[1]=p[mid+1];
 964                 c.p[2]=p[0];
 965                 c.n=3;
 966                 if (c.relationpoint(q))return mid;
 967                 return -1;
 968             }
 969             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>0)
 970             {
 971                 low=mid+1;
 972             }
 973             else
 974             {
 975                 high=mid-1;
 976             }
 977         }
 978         return -1;
 979     }
 980
 981     //ADD
 982     //最小矩形面积覆盖
 983     //A必须是凸包(而且是逆时针顺序)
 984     //Uva   10173
 985     double cross(point A,point B,point C)
 986     {}
 987     double dot(point A,point B,point C)
 988     {}
 989     double minRectangleCover(polygon A)
 990     {}
 991
 992     //ADD
 993     //直线切凸多边形
 994     //多边形是逆时针的,在q1q2的左侧
 995     //HDU3982
 996     /*
 997     vector<point> convexcut(const vector<point> &ps,point q1,point q2)
 998     {
 999         vector<point> qs;
1000         int n=ps.size();
1001         for (int i=0;i<n;i++)
1002         {
1003             point p1=ps[i],p2=ps[(i+1)%n];
1004             int d1=sgn((q2-q1)^(p1-q1)),d2=sgn((q2-q1)^(p2-q1));
1005             if (d1>=0)
1006                 qs.push_back(p1);
1007             if (d1*d2<0)
1008                 qs.push_back(line(p1,p2).crosspoint(line(q1,q2)));
1009         }
1010         return qs;
1011     }
1012     */
1013 };
1014
1015 //ADD
1016 //直线切凸多边形
1017 //多边形是逆时针的,在q1q2的左侧
1018 //HDU3982
1019 vector<point> convexcut(const vector<point> &ps,point q1,point q2)
1020 {
1021     vector<point> qs;
1022     int n=ps.size();
1023     for (int i=0; i<n; i++)
1024     {
1025         point p1=ps[i],p2=ps[(i+1)%n];
1026         int d1=sgn((q2-q1)^(p1-q1)),d2=sgn((q2-q1)^(p2-q1));
1027         if (d1>=0)
1028             qs.push_back(p1);
1029         if (d1*d2<0)
1030             qs.push_back(line(p1,p2).crosspoint(line(q1,q2)));
1031     }
1032     return qs;
1033 }
1034
1035 double CutLine[10000][10];
1036 point Cherry;
1037 int TotalTimes,n;
1038 double r;
1039
1040 int main()
1041 {
1042     freopen("in.txt","r",stdin);
1043
1044     cin>>TotalTimes;
1045     for (int Times=1;Times<=TotalTimes;Times++)
1046     {
1047         //cin>>r>>n;
1048         scanf("%lf%d",&r,&n);
1049         circle Cake=circle(point(0.00,0.00),r);
1050         vector<point> BigPolygon;
1051         BigPolygon.push_back(point(-r,r));
1052         BigPolygon.push_back(point(-r,-r));
1053         BigPolygon.push_back(point(r,-r));
1054         BigPolygon.push_back(point(r,r));
1055
1056         for (int i=1;i<=n;i++)
1057             scanf("%lf%lf%lf%lf",&CutLine[i][1],&CutLine[i][2],&CutLine[i][3],&CutLine[i][4]);
1058             //cin>>CutLine[i][1]>>CutLine[i][2]>>CutLine[i][3]>>CutLine[i][4];
1059
1060         Cherry.input();
1061
1062         for (int i=1;i<=n;i++)
1063         {
1064             line cut(point(CutLine[i][1],CutLine[i][2]),point(CutLine[i][3],CutLine[i][4]));
1065             if (cut.relation(Cherry)==2)
1066             {
1067                 //cut=line(point(CutLine[i][3],CutLine[i][4]),point(CutLine[i][1],CutLine[i][2]));
1068                 BigPolygon=convexcut(BigPolygon,point(CutLine[i][3],CutLine[i][4]),point(CutLine[i][1],CutLine[i][2]));
1069             }
1070             else
1071             {
1072                 BigPolygon=convexcut(BigPolygon,point(CutLine[i][1],CutLine[i][2]),point(CutLine[i][3],CutLine[i][4]));
1073             }
1074         }
1075
1076         polygon Bigpolygon;     Bigpolygon.n=0;
1077         for (vector<point>::iterator i=BigPolygon.begin();i!=BigPolygon.end();i++)
1078         {
1079             point tmp=*i;
1080             Bigpolygon.add(tmp);
1081         }
1082         //double ans=Bigpolygon.getarea();
1083         double CakeArea=Cake.area();
1084         double ans=Bigpolygon.areacircle(Cake);
1085         ans=ans/CakeArea*100;
1086         printf("Case %d: %.5lf%%\n",Times,ans);
1087     }
1088     return 0;
1089 }

Reference:http://blog.csdn.net/zxy_snow/article/details/6739561

话说自从开始刷计算几何之后发现自己代码风格越来越屎了,满满的工程代码既视感。。【逃

时间: 2024-10-22 06:12:37

hdu3982 直线切多边形的相关文章

opengl基础学习专题 (二) 点直线和多边形

题外话 随着学习的增长,越来越觉得自己很水.关于上一篇博文中推荐用一个 学习opengl的 基于VS2015的 simplec框架.存在 一些问题. 1.这个框架基于VS 的Debug 模式下,没有考虑Release版本 2.这个版本中chead,c基础头文件中有些宏设计的不好,例如 //4.0 控制台打印错误信息 #ifndef CERR #define CERR(fmt,...) fprintf(stderr,fmt,##__VA_ARGS__),putchar('\n') #endif/*

canvas绘制直线和多边形基本操作

<!DOCTYPE HTML> <html lang="en"> <body> <canvas id="canvas" width="1024" height="768" style="border:1px solid #aaa;display:block;margin:0 auto;"> 您的浏览器不支持 canvas 标签. </canvas>

BZOJ 1091([SCOI2003]分割多边形-分割直线)

1091: [SCOI2003]分割多边形 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 223  Solved: 82 [Submit][Status] Description 有一个凸p边形(p<=8).我们希望通过分割得到它.一開始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m).每次你能够选择一条直线把当前图形分割成两部分,保留当中一个部分(还有一部分扔掉)分割线的长度为此直线在多边

BZOJ 1091([SCOI2003]切割多边形-切割直线)

1091: [SCOI2003]切割多边形 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 223  Solved: 82 [Submit][Status] Description 有一个凸p边形(p<=8),我们希望通过切割得到它.一开始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m).每次你可以选择一条直线把当前图形切割成两部分,保留其中一个部分(另一部分扔掉)切割线的长度为此直线在多边形

任意多边形切割/裁剪(附C#代码实现)

本实现主要参考了发表于2003年<软件学报>的<一个有效的多边形裁剪算法>(刘勇奎,高云,黄有群)这篇论文,所使用的理论与算法大都基于本文,对论文中部分阐述进行了详细解释,并提取了论文中一些重要的理论加以汇总.另外对于论文描述无法处理的一些情况也进行了试探性的分析. 多边形裁剪用于裁剪掉被裁剪多边形(又称为实体多边形,后文用S表示)位于窗口(又称为裁剪多边形,后文用C表示)之外的部分.裁剪的结果多边形是由实体多边形位于裁剪多边形内的边界和裁剪多边形位于实体多边形内的边界组成的.见下

HDU 3982 半平面交+圆与多边形面积交

Harry Potter and J.K.Rowling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 685    Accepted Submission(s): 210 Problem Description In July 31st, last month, the author of the famous novel seri

matlab练习程序(射线法判断点与多边形关系)

依然是计算几何. 射线法判断点与多边形关系原理如下: 从待判断点引出一条射线,射线与多边形相交,如果交点为偶数,则点不在多边形内,如果交点为奇数,则点在多边形内. 原理虽是这样,有些细节还是要注意一下,比如射线过多边形顶点或射线与多边形其中一边重合等情况还需特别判断. 这里就不特别判断了,因为我只是熟悉原理,并不是实际运用. 好吧,我实际是太懒了,不想判断了. 结果如下: 结果图和线性分类器的组合有几分相似. matlab代码如下: clear all;close all;clc; polyn=

openGL学习笔记三 : 绘制点、线以及多边形

前面我们绘制了一个矩形, 现在就一并来看看如何绘制点.线以及多边形吧. 一. 点 在openGL里面有这样一系列的函数, 他们以glVertex开头, 没错, 这就是我们需要的绘制点的函数, 来看看有哪些: WINGDIAPI void APIENTRY glVertex2d (GLdouble x, GLdouble y); WINGDIAPI void APIENTRY glVertex2dv (const GLdouble *v); WINGDIAPI void APIENTRY glVe

bzoj1091: [SCOI2003]切割多边形

Description 有一个凸p边形(p<=8),我们希望通过切割得到它.一开始的时候,你有一个n*m的矩形,即它的四角的坐标分别为(0,0), (0,m), (n,0), (n,m).每次你可以选择一条直线把当前图形切割成两部分,保留其中一个部分(另一部分扔掉)切割线的长度为此直线在多边形内部的部分的长度.求出最短的切割线总长度.下面是一个例子.我们需要得到中间的多边形. 分别沿着直线1,2,3,4进行切割即可,得到中间的四边形. Input 第一行有两个整数n, m(0 < n,m &l