Gym-100935I Farm 计算几何 圆和矩形面积交
题意:就是给你一个圆,和你一个矩形,求面积并,且 保证是一种情况:三角剖分后 一个点在圆内 两个在圆外
题解:可以直接上圆与凸多边形交的板子,也可以由这题实际情况,面积等于扇形减两个三角形
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int T; 6 double dx,dy,yx,ux,uy,rx,ry,R; 7 double s1,s2,s3,x1,y1,x2,y2,cosA; 8 scanf("%d",&T); 9 for (int i=1;i<=T;i++) 10 { 11 scanf("%lf%lf%lf",&rx,&ry,&R); 12 scanf("%lf%lf%lf%lf",&dx,&dy,&ux,&uy); 13 dx-=rx;ux-=rx;dy-=ry;uy-=ry; 14 x1=dx; 15 y1=-sqrt(R*R-x1*x1); 16 y2=uy; 17 x2=sqrt(R*R-y2*y2); 18 cosA=acos((x1*x2+y1*y2)/sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2))); 19 s1=R*R*cosA/2; 20 s2=x1*(y2-y1)/2; 21 s3=y2*(x1-x2)/2; 22 printf("Case %d: %.5lf\n",i,s1-s2-s3); 23 } 24 }
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 T,n=4; 75 double rx,ry,R; 76 scanf("%d",&T); 77 for (int ii=1;ii<=T;ii++) 78 { 79 scanf("%lf%lf%lf",&rx,&ry,&R); 80 scanf("%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[3].x,&p[3].y); 81 p[2].x=p[1].x;p[2].y=p[3].y; 82 p[4].x=p[3].x;p[4].y=p[1].y; 83 p[5]=p[1]; 84 Point O(rx,ry); 85 for (int i=1;i<=n+1;i++) p[i]=p[i]-O; 86 O=Point(0,0); 87 double sum=0; 88 for (int i=1;i<=n;i++) 89 { 90 int j=i+1; 91 double s=area(p[i],p[j],R); 92 if (cross(O,p[i],p[j])>0) sum+=s;else sum-=s; 93 } 94 printf("Case %d: %.5lf\n",ii,fabs(sum)); 95 } 96 return 0; 97 }
Anderyi!