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

poj3675 求多边形与圆的面积交

时间:2015-02-07 18:48:49      阅读:434      评论:0      收藏:0      [点我收藏+]

标签:

题意:给出多边形的顶点坐标、圆的圆心坐标和半径,求面积交

 

sol:又是模板题啦= =

注意poj的C++好像认不出hypot函数,要稍微改写一下。

hypot(double x,double y):即返回sqrt(x*x+y*y)的值

 

技术分享
  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-8;
 32 const double pi=acos(-1.0);
 33 const double inf=1e20;
 34 const int maxp=1111;
 35 int dblcmp(double d)
 36 {
 37     if (fabs(d)<eps)return 0;
 38     return d>eps?1:-1;
 39 }
 40 inline double sqr(double x){return x*x;}
 41 struct point
 42 {
 43     double x,y;
 44     point(){}
 45     point(double _x,double _y):
 46     x(_x),y(_y){};
 47     void input()
 48     {
 49         scanf("%lf%lf",&x,&y);
 50     }
 51     void output()
 52     {
 53         printf("%.2f %.2f\n",x,y);
 54     }
 55     bool operator==(point a)const
 56     {
 57         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
 58     }
 59     bool operator<(point a)const
 60     {
 61         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
 62     }
 63     double len()
 64     {
 65         //return hypot(x,y);
 66         return (sqrt(x*x+y*y));
 67     }
 68     double len2()
 69     {
 70         return x*x+y*y;
 71     }
 72     double distance(point p)
 73     {
 74         //return hypot(x-p.x,y-p.y);
 75         double tx=x-p.x,ty=y-p.y;
 76         return (sqrt(tx*tx+ty*ty));
 77     }
 78     point add(point p)
 79     {
 80         return point(x+p.x,y+p.y);
 81     }
 82     point sub(point p)
 83     {
 84         return point(x-p.x,y-p.y);
 85     }
 86     point mul(double b)
 87     {
 88         return point(x*b,y*b);
 89     }
 90     point div(double b)
 91     {
 92         return point(x/b,y/b);
 93     }
 94     double dot(point p)
 95     {
 96         return x*p.x+y*p.y;
 97     }
 98     double det(point p)
 99     {
100         return x*p.y-y*p.x;
101     }
102     double rad(point a,point b)
103     {
104         point p=*this;
105         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
106     }
107     point trunc(double r)
108     {
109         double l=len();
110         if (!dblcmp(l))return *this;
111         r/=l;
112         return point(x*r,y*r);
113     }
114     point rotleft()
115     {
116         return point(-y,x);
117     }
118     point rotright()
119     {
120         return point(y,-x);
121     }
122     point rotate(point p,double angle)//绕点p逆时针旋转angle角度
123     {
124         point v=this->sub(p);
125         double c=cos(angle),s=sin(angle);
126         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
127     }
128 };
129 struct line
130 {
131     point a,b;
132     line(){}
133     line(point _a,point _b)
134     {
135         a=_a;
136         b=_b;
137     }
138     bool operator==(line v)
139     {
140         return (a==v.a)&&(b==v.b);
141     }
142     //倾斜角angle
143     line(point p,double angle)
144     {
145         a=p;
146         if (dblcmp(angle-pi/2)==0)
147         {
148             b=a.add(point(0,1));
149         }
150         else
151         {
152             b=a.add(point(1,tan(angle)));
153         }
154     }
155     //ax+by+c=0
156     line(double _a,double _b,double _c)
157     {
158         if (dblcmp(_a)==0)
159         {
160             a=point(0,-_c/_b);
161             b=point(1,-_c/_b);
162         }
163         else if (dblcmp(_b)==0)
164         {
165             a=point(-_c/_a,0);
166             b=point(-_c/_a,1);
167         }
168         else
169         {
170             a=point(0,-_c/_b);
171             b=point(1,(-_c-_a)/_b);
172         }
173     }
174     void input()
175     {
176         a.input();
177         b.input();
178     }
179     void adjust()
180     {
181         if (b<a)swap(a,b);
182     }
183     double length()
184     {
185         return a.distance(b);
186     }
187     double angle()//直线倾斜角 0<=angle<180
188     {
189         double k=atan2(b.y-a.y,b.x-a.x);
190         if (dblcmp(k)<0)k+=pi;
191         if (dblcmp(k-pi)==0)k-=pi;
192         return k;
193     }
194     //点和线段关系
195     //1 在逆时针
196     //2 在顺时针
197     //3 平行
198     int relation(point p)
199     {
200         int c=dblcmp(p.sub(a).det(b.sub(a)));
201         if (c<0)return 1;
202         if (c>0)return 2;
203         return 3;
204     }
205     bool pointonseg(point p)
206     {
207         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
208     }
209     bool parallel(line v)
210     {
211         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
212     }
213     //2 规范相交
214     //1 非规范相交
215     //0 不相交
216     int segcrossseg(line v)
217     {
218         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
219         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
220         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
221         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
222         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
223         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
224                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
225                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
226                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
227     }
228     int linecrossseg(line v)//*this seg v line
229     {
230         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
231         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
232         if ((d1^d2)==-2)return 2;
233         return (d1==0||d2==0);
234     }
235     //0 平行
236     //1 重合
237     //2 相交
238     int linecrossline(line v)
239     {
240         if ((*this).parallel(v))
241         {
242             return v.relation(a)==3;
243         }
244         return 2;
245     }
246     point crosspoint(line v)
247     {
248         double a1=v.b.sub(v.a).det(a.sub(v.a));
249         double a2=v.b.sub(v.a).det(b.sub(v.a));
250         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
251     }
252     double dispointtoline(point p)
253     {
254         return fabs(p.sub(a).det(b.sub(a)))/length();
255     }
256     double dispointtoseg(point p)
257     {
258         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
259         {
260             return min(p.distance(a),p.distance(b));
261         }
262         return dispointtoline(p);
263     }
264     point lineprog(point p)
265     {
266         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
267     }
268     point symmetrypoint(point p)
269     {
270         point q=lineprog(p);
271         return point(2*q.x-p.x,2*q.y-p.y);
272     }
273 };
274 struct circle
275 {
276     point p;
277     double r;
278     circle(){}
279     circle(point _p,double _r):
280     p(_p),r(_r){};
281     circle(double x,double y,double _r):
282     p(point(x,y)),r(_r){};
283     circle(point a,point b,point c)//三角形的外接圆
284     {
285         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())));
286         r=p.distance(a);
287     }
288     circle(point a,point b,point c,bool t)//三角形的内切圆
289     {
290         line u,v;
291         double m=atan2(b.y-a.y,b.x-a.x),n=atan2(c.y-a.y,c.x-a.x);
292         u.a=a;
293         u.b=u.a.add(point(cos((n+m)/2),sin((n+m)/2)));
294         v.a=b;
295         m=atan2(a.y-b.y,a.x-b.x),n=atan2(c.y-b.y,c.x-b.x);
296         v.b=v.a.add(point(cos((n+m)/2),sin((n+m)/2)));
297         p=u.crosspoint(v);
298         r=line(a,b).dispointtoseg(p);
299     }
300     void input()
301     {
302         p.input();
303         scanf("%lf",&r);
304     }
305     void output()
306     {
307         printf("%.2lf %.2lf %.2lf\n",p.x,p.y,r);
308     }
309     bool operator==(circle v)
310     {
311         return ((p==v.p)&&dblcmp(r-v.r)==0);
312     }
313     bool operator<(circle v)const
314     {
315         return ((p<v.p)||(p==v.p)&&dblcmp(r-v.r)<0);
316     }
317     double area()
318     {
319         return pi*sqr(r);
320     }
321     double circumference()
322     {
323         return 2*pi*r;
324     }
325     //0 圆外
326     //1 圆上
327     //2 圆内
328     int relation(point b)
329     {
330         double dst=b.distance(p);
331         if (dblcmp(dst-r)<0)return 2;
332         if (dblcmp(dst-r)==0)return 1;
333         return 0;
334     }
335     int relationseg(line v)
336     {
337         double dst=v.dispointtoseg(p);
338         if (dblcmp(dst-r)<0)return 2;
339         if (dblcmp(dst-r)==0)return 1;
340         return 0;
341     }
342     int relationline(line v)
343     {
344         double dst=v.dispointtoline(p);
345         if (dblcmp(dst-r)<0)return 2;
346         if (dblcmp(dst-r)==0)return 1;
347         return 0;
348     }
349     //过a b两点 半径r的两个圆
350     int getcircle(point a,point b,double r,circle&c1,circle&c2)
351     {
352         circle x(a,r),y(b,r);
353         int t=x.pointcrosscircle(y,c1.p,c2.p);
354         if (!t)return 0;
355         c1.r=c2.r=r;
356         return t;
357     }
358     //与直线u相切 过点q 半径r1的圆
359     int getcircle(line u,point q,double r1,circle &c1,circle &c2)
360     {
361         double dis=u.dispointtoline(q);
362         if (dblcmp(dis-r1*2)>0)return 0;
363         if (dblcmp(dis)==0)
364         {
365             c1.p=q.add(u.b.sub(u.a).rotleft().trunc(r1));
366             c2.p=q.add(u.b.sub(u.a).rotright().trunc(r1));
367             c1.r=c2.r=r1;
368             return 2;
369         }
370         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)));
371         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)));
372         circle cc=circle(q,r1);
373         point p1,p2;
374         if (!cc.pointcrossline(u1,p1,p2))cc.pointcrossline(u2,p1,p2);
375         c1=circle(p1,r1);
376         if (p1==p2)
377         {
378             c2=c1;return 1;
379         }
380         c2=circle(p2,r1);
381         return 2;
382     }
383     //同时与直线u,v相切 半径r1的圆
384     int getcircle(line u,line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4)
385     {
386         if (u.parallel(v))return 0;
387         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)));
388         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)));
389         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)));
390         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)));
391         c1.r=c2.r=c3.r=c4.r=r1;
392         c1.p=u1.crosspoint(v1);
393         c2.p=u1.crosspoint(v2);
394         c3.p=u2.crosspoint(v1);
395         c4.p=u2.crosspoint(v2);
396         return 4;
397     }
398     //同时与不相交圆cx,cy相切 半径为r1的圆
399     int getcircle(circle cx,circle cy,double r1,circle&c1,circle&c2)
400     {
401         circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);
402         int t=x.pointcrosscircle(y,c1.p,c2.p);
403         if (!t)return 0;
404         c1.r=c2.r=r1;
405         return t;
406     }
407     int pointcrossline(line v,point &p1,point &p2)//求与线段交要先判断relationseg
408     {
409         if (!(*this).relationline(v))return 0;
410         point a=v.lineprog(p);
411         double d=v.dispointtoline(p);
412         d=sqrt(r*r-d*d);
413         if (dblcmp(d)==0)
414         {
415             p1=a;
416             p2=a;
417             return 1;
418         }
419         p1=a.sub(v.b.sub(v.a).trunc(d));
420         p2=a.add(v.b.sub(v.a).trunc(d));
421         return 2;
422     }
423     //5 相离
424     //4 外切
425     //3 相交
426     //2 内切
427     //1 内含
428     int relationcircle(circle v)
429     {
430         double d=p.distance(v.p);
431         if (dblcmp(d-r-v.r)>0)return 5;
432         if (dblcmp(d-r-v.r)==0)return 4;
433         double l=fabs(r-v.r);
434         if (dblcmp(d-r-v.r)<0&&dblcmp(d-l)>0)return 3;
435         if (dblcmp(d-l)==0)return 2;
436         if (dblcmp(d-l)<0)return 1;
437     }
438     int pointcrosscircle(circle v,point &p1,point &p2)
439     {
440         int rel=relationcircle(v);
441         if (rel==1||rel==5)return 0;
442         double d=p.distance(v.p);
443         double l=(d+(sqr(r)-sqr(v.r))/d)/2;
444         double h=sqrt(sqr(r)-sqr(l));
445         p1=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotleft().trunc(h)));
446         p2=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotright().trunc(h)));
447         if (rel==2||rel==4)
448         {
449             return 1;
450         }
451         return 2;
452     }
453     //过一点做圆的切线 (先判断点和圆关系)
454     int tangentline(point q,line &u,line &v)
455     {
456         int x=relation(q);
457         if (x==2)return 0;
458         if (x==1)
459         {
460             u=line(q,q.add(q.sub(p).rotleft()));
461             v=u;
462             return 1;
463         }
464         double d=p.distance(q);
465         double l=sqr(r)/d;
466         double h=sqrt(sqr(r)-sqr(l));
467         u=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotleft().trunc(h))));
468         v=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotright().trunc(h))));
469         return 2;
470     }
471     double areacircle(circle v)
472     {
473         int rel=relationcircle(v);
474         if (rel>=4)return 0.0;
475         if (rel<=2)return min(area(),v.area());
476         double d=p.distance(v.p);
477         double hf=(r+v.r+d)/2.0;
478         double ss=2*sqrt(hf*(hf-r)*(hf-v.r)*(hf-d));
479         double a1=acos((r*r+d*d-v.r*v.r)/(2.0*r*d));
480         a1=a1*r*r;
481         double a2=acos((v.r*v.r+d*d-r*r)/(2.0*v.r*d));
482         a2=a2*v.r*v.r;
483         return a1+a2-ss;
484     }
485     double areatriangle(point a,point b)
486     {
487         if (dblcmp(p.sub(a).det(p.sub(b))==0))return 0.0;
488         point q[5];
489         int len=0;
490         q[len++]=a;
491         line l(a,b);
492         point p1,p2;
493         if (pointcrossline(l,q[1],q[2])==2)
494         {
495             if (dblcmp(a.sub(q[1]).dot(b.sub(q[1])))<0)q[len++]=q[1];
496             if (dblcmp(a.sub(q[2]).dot(b.sub(q[2])))<0)q[len++]=q[2];
497         }
498         q[len++]=b;
499         if (len==4&&(dblcmp(q[0].sub(q[1]).dot(q[2].sub(q[1])))>0))swap(q[1],q[2]);
500         double res=0;
501         int i;
502         for (i=0;i<len-1;i++)
503         {
504             if (relation(q[i])==0||relation(q[i+1])==0)
505             {
506                 double arg=p.rad(q[i],q[i+1]);
507                 res+=r*r*arg/2.0;
508             }
509             else
510             {
511                 res+=fabs(q[i].sub(p).det(q[i+1].sub(p))/2.0);
512             }
513         }
514         return res;
515     }
516 };
517 struct polygon
518 {
519     int n;
520     point p[maxp];
521     line l[maxp];
522     void input(int X)
523     {
524         n=X;
525         for (int i=0;i<n;i++)
526         {
527             p[i].input();
528         }
529     }
530     void add(point q)
531     {
532         p[n++]=q;
533     }
534     void getline()
535     {
536         for (int i=0;i<n;i++)
537         {
538             l[i]=line(p[i],p[(i+1)%n]);
539         }
540     }
541     struct cmp
542     {
543         point p;
544         cmp(const point &p0){p=p0;}
545         bool operator()(const point &aa,const point &bb)
546         {
547             point a=aa,b=bb;
548             int d=dblcmp(a.sub(p).det(b.sub(p)));
549             if (d==0)
550             {
551                 return dblcmp(a.distance(p)-b.distance(p))<0;
552             }
553             return d>0;
554         }
555     };
556     void norm()
557     {
558         point mi=p[0];
559         for (int i=1;i<n;i++)mi=min(mi,p[i]);
560         sort(p,p+n,cmp(mi));
561     }
562     void getconvex(polygon &convex)
563     {
564         int i,j,k;
565         sort(p,p+n);
566         convex.n=n;
567         for (i=0;i<min(n,2);i++)
568         {
569             convex.p[i]=p[i];
570         }
571         if (n<=2)return;
572         int &top=convex.n;
573         top=1;
574         for (i=2;i<n;i++)
575         {
576             while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
577                 top--;
578             convex.p[++top]=p[i];
579         }
580         int temp=top;
581         convex.p[++top]=p[n-2];
582         for (i=n-3;i>=0;i--)
583         {
584             while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
585                 top--;
586             convex.p[++top]=p[i];
587         }
588     }
589     bool isconvex()
590     {
591         bool s[3];
592         memset(s,0,sizeof(s));
593         int i,j,k;
594         for (i=0;i<n;i++)
595         {
596             j=(i+1)%n;
597             k=(j+1)%n;
598             s[dblcmp(p[j].sub(p[i]).det(p[k].sub(p[i])))+1]=1;
599             if (s[0]&&s[2])return 0;
600         }
601         return 1;
602     }
603     //3 点上
604     //2 边上
605     //1 内部
606     //0 外部
607     int relationpoint(point q)
608     {
609         int i,j;
610         for (i=0;i<n;i++)
611         {
612             if (p[i]==q)return 3;
613         }
614         getline();
615         for (i=0;i<n;i++)
616         {
617             if (l[i].pointonseg(q))return 2;
618         }
619         int cnt=0;
620         for (i=0;i<n;i++)
621         {
622             j=(i+1)%n;
623             int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
624             int u=dblcmp(p[i].y-q.y);
625             int v=dblcmp(p[j].y-q.y);
626             if (k>0&&u<0&&v>=0)cnt++;
627             if (k<0&&v<0&&u>=0)cnt--;
628         }
629         return cnt!=0;
630     }
631     //1 在多边形内长度为正
632     //2 相交或与边平行
633     //0 无任何交点
634     int relationline(line u)
635     {
636         int i,j,k=0;
637         getline();
638         for (i=0;i<n;i++)
639         {
640             if (l[i].segcrossseg(u)==2)return 1;
641             if (l[i].segcrossseg(u)==1)k=1;
642         }
643         if (!k)return 0;
644         vector<point>vp;
645         for (i=0;i<n;i++)
646         {
647             if (l[i].segcrossseg(u))
648             {
649                 if (l[i].parallel(u))
650                 {
651                     vp.pb(u.a);
652                     vp.pb(u.b);
653                     vp.pb(l[i].a);
654                     vp.pb(l[i].b);
655                     continue;
656                 }
657                 vp.pb(l[i].crosspoint(u));
658             }
659         }
660         sort(vp.begin(),vp.end());
661         int sz=vp.size();
662         for (i=0;i<sz-1;i++)
663         {
664             point mid=vp[i].add(vp[i+1]).div(2);
665             if (relationpoint(mid)==1)return 1;
666         }
667         return 2;
668     }
669     //直线u切割凸多边形左侧
670     //注意直线方向
671     void convexcut(line u,polygon &po)
672     {
673         int i,j,k;
674         int &top=po.n;
675         top=0;
676         for (i=0;i<n;i++)
677         {
678             int d1=dblcmp(p[i].sub(u.a).det(u.b.sub(u.a)));
679             int d2=dblcmp(p[(i+1)%n].sub(u.a).det(u.b.sub(u.a)));
680             if (d1>=0)po.p[top++]=p[i];
681             if (d1*d2<0)po.p[top++]=u.crosspoint(line(p[i],p[(i+1)%n]));
682         }
683     }
684     double getcircumference()
685     {
686         double sum=0;
687         int i;
688         for (i=0;i<n;i++)
689         {
690             sum+=p[i].distance(p[(i+1)%n]);
691         }
692         return sum;
693     }
694     double getarea()
695     {
696         double sum=0;
697         int i;
698         for (i=0;i<n;i++)
699         {
700             sum+=p[i].det(p[(i+1)%n]);
701         }
702         return fabs(sum)/2;
703     }
704     bool getdir()//1代表逆时针 0代表顺时针
705     {
706         double sum=0;
707         int i;
708         for (i=0;i<n;i++)
709         {
710             sum+=p[i].det(p[(i+1)%n]);
711         }
712         if (dblcmp(sum)>0)return 1;
713         return 0;
714     }
715     point getbarycentre()
716     {
717         point ret(0,0);
718         double area=0;
719         int i;
720         for (i=1;i<n-1;i++)
721         {
722             double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0]));
723             if (dblcmp(tmp)==0)continue;
724             area+=tmp;
725             ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp;
726             ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp;
727         }
728         if (dblcmp(area))ret=ret.div(area);
729         return ret;
730     }
731     double areaintersection(polygon po)
732     {
733     }
734     double areaunion(polygon po)
735     {
736         return getarea()+po.getarea()-areaintersection(po);
737     }
738     double areacircle(circle c)
739     {
740         int i,j,k,l,m;
741         double ans=0;
742         for (i=0;i<n;i++)
743         {
744             int j=(i+1)%n;
745             if (dblcmp(p[j].sub(c.p).det(p[i].sub(c.p)))>=0)
746             {
747                 ans+=c.areatriangle(p[i],p[j]);
748             }
749             else
750             {
751                 ans-=c.areatriangle(p[i],p[j]);
752             }
753         }
754         return fabs(ans);
755     }
756     //多边形和圆关系
757     //0 一部分在圆外
758     //1 与圆某条边相切
759     //2 完全在圆内
760     int relationcircle(circle c)
761     {
762         getline();
763         int i,x=2;
764         if (relationpoint(c.p)!=1)return 0;
765         for (i=0;i<n;i++)
766         {
767             if (c.relationseg(l[i])==2)return 0;
768             if (c.relationseg(l[i])==1)x=1;
769         }
770         return x;
771     }
772     void find(int st,point tri[],circle &c)
773     {
774         if (!st)
775         {
776             c=circle(point(0,0),-2);
777         }
778         if (st==1)
779         {
780             c=circle(tri[0],0);
781         }
782         if (st==2)
783         {
784             c=circle(tri[0].add(tri[1]).div(2),tri[0].distance(tri[1])/2.0);
785         }
786         if (st==3)
787         {
788             c=circle(tri[0],tri[1],tri[2]);
789         }
790     }
791     void solve(int cur,int st,point tri[],circle &c)
792     {
793         find(st,tri,c);
794         if (st==3)return;
795         int i;
796         for (i=0;i<cur;i++)
797         {
798             if (dblcmp(p[i].distance(c.p)-c.r)>0)
799             {
800                 tri[st]=p[i];
801                 solve(i,st+1,tri,c);
802             }
803         }
804     }
805     circle mincircle()//点集最小圆覆盖
806     {
807         random_shuffle(p,p+n);
808         point tri[4];
809         circle c;
810         solve(n,0,tri,c);
811         return c;
812     }
813     int circlecover(double r)//单位圆覆盖
814     {
815         int ans=0,i,j;
816         vector<pair<double,int> >v;
817         for (i=0;i<n;i++)
818         {
819             v.clear();
820             for (j=0;j<n;j++)if (i!=j)
821             {
822                 point q=p[i].sub(p[j]);
823                 double d=q.len();
824                 if (dblcmp(d-2*r)<=0)
825                 {
826                     double arg=atan2(q.y,q.x);
827                     if (dblcmp(arg)<0)arg+=2*pi;
828                     double t=acos(d/(2*r));
829                     v.push_back(make_pair(arg-t+2*pi,-1));
830                     v.push_back(make_pair(arg+t+2*pi,1));
831                 }
832             }
833             sort(v.begin(),v.end());
834             int cur=0;
835             for (j=0;j<v.size();j++)
836             {
837                 if (v[j].second==-1)++cur;
838                 else --cur;
839                 ans=max(ans,cur);
840             }
841         }
842         return ans+1;
843     }
844     int pointinpolygon(point q)//点在凸多边形内部的判定
845     {
846         if (getdir())reverse(p,p+n);
847         if (dblcmp(q.sub(p[0]).det(p[n-1].sub(p[0])))==0)
848         {
849             if (line(p[n-1],p[0]).pointonseg(q))return n-1;
850             return -1;
851         }
852         int low=1,high=n-2,mid;
853         while (low<=high)
854         {
855             mid=(low+high)>>1;
856             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)
857             {
858                 polygon c;
859                 c.p[0]=p[mid];
860                 c.p[1]=p[mid+1];
861                 c.p[2]=p[0];
862                 c.n=3;
863                 if (c.relationpoint(q))return mid;
864                 return -1;
865             }
866             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>0)
867             {
868                 low=mid+1;
869             }
870             else
871             {
872                 high=mid-1;
873             }
874         }
875         return -1;
876     }
877 };
878 
879 
880 circle CR;  double R;
881 polygon PL;
882 int n;
883 
884 int main()
885 {
886     while(cin>>R)
887     {
888         CR=circle(point(0,0),R);
889         cin>>n;
890         PL.input(n);
891 
892         double ans=PL.areacircle(CR);
893         printf("%.2lf\n",ans);
894     }
895 
896     return 0;
897 }
View Code

 

poj3675 求多边形与圆的面积交

标签:

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

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