题意:给定一个不自交的多边形,要求和圆心在原点的圆的面积交.
思路:同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 }
时间: 2024-10-10 10:56:10