POJ 3675 Telescope

题意:给定一个不自交的多边形,要求和圆心在原点的圆的面积交.

思路:同POJ2986,是加强版

代码:

  1 #include<algorithm>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<iostream>
  6 struct Point{
  7     double x,y;
  8     Point(){}
  9     Point(double x0,double y0):x(x0),y(y0){}
 10 }p[200005],a[5],O;
 11 struct Line{
 12     Point s,e;
 13     Line(){}
 14     Line(Point s0,Point e0):s(s0),e(e0){}
 15 };
 16 int n;
 17 double R;
 18 const double eps=1e-8;
 19 const double Pi=acos(-1);
 20 double sgn(double x){
 21     if (x>eps) return 1.0;
 22     if (x<-eps) return -1.0;
 23     return 0;
 24 }
 25 Point operator *(Point p1,double x){
 26     return Point(p1.x*x,p1.y*x);
 27 }
 28 Point operator /(Point p1,double x){
 29     return Point(p1.x/x,p1.y/x);
 30 }
 31 double operator /(Point p1,Point p2){
 32     return p1.x*p2.x+p1.y*p2.y;
 33 }
 34 double operator *(Point p1,Point p2){
 35     return p1.x*p2.y-p1.y*p2.x;
 36 }
 37 Point operator +(Point p1,Point p2){
 38     return Point(p1.x+p2.x,p1.y+p2.y);
 39 }
 40 Point operator -(Point p1,Point p2){
 41     return Point(p1.x-p2.x,p1.y-p2.y);
 42 }
 43 double dis(Point p1){
 44     return sqrt(p1.x*p1.x+p1.y*p1.y);
 45 }
 46 double dis(Point p1,Point p2){
 47     return dis(Point(p1.x-p2.x,p1.y-p2.y));
 48 }
 49 double sqr(double x){
 50     return x*x;
 51 }
 52 double dist_line(Line p){
 53     double A,B,C,dist;
 54     A=p.s.y-p.e.y;
 55     B=p.s.x-p.e.x;
 56     C=p.s.x*p.e.y-p.s.y*p.e.x;
 57     dist=fabs(C)/sqrt(sqr(A)+sqr(B));
 58     return dist;
 59 }
 60 double get_cos(double a,double b,double c){
 61     return (b*b+c*c-a*a)/(2*b*c);
 62 }
 63 double get_angle(Point p1,Point p2){
 64     if (!sgn(dis(p1))||!sgn(dis(p2))) return 0.0;
 65     double A,B,C;
 66     A=dis(p1);
 67     B=dis(p2);
 68     C=dis(p1,p2);
 69     if (C<=eps) return 0.0;
 70     return acos(get_cos(C,A,B));
 71 }
 72 Point get_point(Point p){
 73     double T=sqr(p.x)+sqr(p.y);
 74     return Point(sgn(p.x)*sqrt(sqr(p.x)/T),sgn(p.y)*sqrt(sqr(p.y)/T));
 75 }
 76 double S(Point p1,Point p2,Point p3){
 77     return fabs((p2-p1)*(p3-p1))/2;
 78 }
 79 double work(Point p1,Point p2){
 80     double f=sgn(p1*p2),res=0;
 81     if (!sgn(f)||!sgn(dis(p1))||!sgn(dis(p2))) return 0.0;
 82     double l=dist_line(Line(p1,p2));
 83     double a=dis(p1);
 84     double b=dis(p2);
 85     double c=dis(p1,p2);
 86     if (a<=R&&b<=R){
 87         return fabs(p1*p2)/2.0*f;
 88     }
 89     if (a>=R&&b>=R&&l>=R){
 90         double ang=get_angle(p1,p2);
 91         return fabs((ang/(2.0))*(R*R))*f;
 92     }
 93     if (a>=R&&b>=R&&l<=R&&(get_cos(a,b,c)<=0||get_cos(b,a,c)<=0)){
 94         double ang=get_angle(p1,p2);
 95         return fabs((ang/(2.0))*(R*R))*f;
 96     }
 97     if (a>=R&&b>=R&&l<=R&&(get_cos(a,b,c)>0&&get_cos(b,a,c)>0)){
 98         double dist=dist_line(Line(p1,p2));
 99         double len=sqrt(sqr(R)-sqr(dist))*2.0;
100         double ang1=get_angle(p1,p2);
101         double cos2=get_cos(len,R,R);
102         res+=fabs(len*dist/2.0);
103         double ang2=ang1-acos(cos2);
104         res+=fabs((ang2/(2))*(R*R));
105         return res*f;
106     }
107     if ((a>=R&&b<R)||(a<R&&b>=R)){
108         if (b>a) std::swap(a,b),std::swap(p1,p2);
109         double T=sqr(p1.x-p2.x)+sqr(p1.y-p2.y);
110         Point u=Point(sgn(p1.x-p2.x)*sqrt(sqr(p1.x-p2.x)/T),sgn(p1.y-p2.y)*sqrt(sqr(p1.y-p2.y)/T));
111         double dist=dist_line(Line(p1,p2));
112         double len=sqrt(R*R-dist*dist);
113         double len2=sqrt(sqr(dis(p2))-sqr(dist));
114         if (fabs(dis(p2+u*len2)-dist)<=eps) len+=len2;
115         else len-=len2;
116         Point p=p2+u*len;
117         res+=S(O,p2,p);
118         double ang=get_angle(p1,p);
119         res+=fabs((ang/2.0)*R*R);
120         return res*f;
121     }
122     return 0;
123 }
124 int main(){
125     O=Point(0,0);
126     while (scanf("%lf",&R)!=EOF){
127         scanf("%d",&n);
128         for (int i=1;i<=n;i++)
129          scanf("%lf%lf",&p[i].x,&p[i].y);
130         p[n+1]=p[1];
131         double ans=0;
132         for (int i=1;i<=n;i++)
133          ans+=work(p[i],p[i+1]);
134         ans=fabs(ans);  
135         printf("%.2f\n",ans); 
136     }
137 }

 

posted @ 2016-06-11 20:17  GFY  阅读(327)  评论(0编辑  收藏  举报