Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交
题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交
题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交
打的时候队友说凹的不行,不是板题,后面想想,圆与多边形面积交本来就是拆成有向三角形做的,所以无论凹凸了
1 #include<bits/stdc++.h> 2 #define inf 1000000000000 3 #define M 100009 4 #define eps 1e-12 5 #define PI acos(-1.0) 6 using namespace std; 7 struct Point 8 { 9 double x,y; 10 Point(){} 11 Point(double xx,double yy){x=xx;y=yy;} 12 Point operator -(Point s){return Point(x-s.x,y-s.y);} 13 Point operator +(Point s){return Point(x+s.x,y+s.y);} 14 double operator *(Point s){return x*s.x+y*s.y;} 15 double operator ^(Point s){return x*s.y-y*s.x;} 16 }p[M]; 17 double max(double a,double b){return a>b?a:b;} 18 double min(double a,double b){return a<b?a:b;} 19 double len(Point a){return sqrt(a*a);} 20 double dis(Point a,Point b){return len(b-a);}//两点之间的距离 21 double cross(Point a,Point b,Point c)//叉乘 22 { 23 return (b-a)^(c-a); 24 } 25 double dot(Point a,Point b,Point c)//点乘 26 { 27 return (b-a)*(c-a); 28 } 29 int judge(Point a,Point b,Point c)//判断c是否在ab线段上(前提是c在直线ab上) 30 { 31 if (c.x>=min(a.x,b.x) 32 &&c.x<=max(a.x,b.x) 33 &&c.y>=min(a.y,b.y) 34 &&c.y<=max(a.y,b.y)) return 1; 35 return 0; 36 } 37 double area(Point b,Point c,double r) 38 { 39 Point a(0.0,0.0); 40 if(dis(b,c)<eps) return 0.0; 41 double h=fabs(cross(a,b,c))/dis(b,c); 42 if(dis(a,b)>r-eps&&dis(a,c)>r-eps)//两个端点都在圆的外面则分为两种情况 43 { 44 double angle=acos(dot(a,b,c)/dis(a,b)/dis(a,c)); 45 if(h>r-eps) return 0.5*r*r*angle;else 46 if(dot(b,a,c)>0&&dot(c,a,b)>0) 47 { 48 double angle1=2*acos(h/r); 49 return 0.5*r*r*fabs(angle-angle1)+0.5*r*r*sin(angle1); 50 }else return 0.5*r*r*angle; 51 }else 52 if(dis(a,b)<r+eps&&dis(a,c)<r+eps) return 0.5*fabs(cross(a,b,c));//两个端点都在圆内的情况 53 else//一个端点在圆上一个端点在圆内的情况 54 { 55 if(dis(a,b)>dis(a,c)) swap(b,c);//默认b在圆内 56 if(fabs(dis(a,b))<eps) return 0.0;//ab距离为0直接返回0 57 if(dot(b,a,c)<eps) 58 { 59 double angle1=acos(h/dis(a,b)); 60 double angle2=acos(h/r)-angle1; 61 double angle3=acos(h/dis(a,c))-acos(h/r); 62 return 0.5*dis(a,b)*r*sin(angle2)+0.5*r*r*angle3; 63 }else 64 { 65 double angle1=acos(h/dis(a,b)); 66 double angle2=acos(h/r); 67 double angle3=acos(h/dis(a,c))-angle2; 68 return 0.5*r*dis(a,b)*sin(angle1+angle2)+0.5*r*r*angle3; 69 } 70 } 71 } 72 int main() 73 { 74 int n; 75 double R; 76 scanf("%d%lf",&n,&R); 77 for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); 78 p[n+1]=p[1]; 79 Point O(0,0); 80 for(int i=1;i<=n+1;i++) p[i]=p[i]-O; 81 O=Point(0,0); 82 double sum=0; 83 for(int i=1;i<=n;i++) 84 { 85 int j=i+1; 86 double s=area(p[i],p[j],R); 87 if(cross(O,p[i],p[j])>0) sum+=s; else sum-=s; 88 } 89 printf("%.12lf\n",fabs(sum)); 90 return 0; 91 }
Anderyi!