码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3982 直线切多边形

时间:2015-02-11 20:37:28      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

题意:有一块蛋糕,上面有一颗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 }
View Code

 

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

 

 

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

hdu3982 直线切多边形

标签:

原文地址:http://www.cnblogs.com/pdev/p/4286912.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!