题中给了 两个同心圆, 一个大圆一个小圆,然后再给了一个大圆一个小圆也是同心圆,求这两个圆环相交的面积,用两个大圆面积减去两倍大小圆面积交加上两个小圆面积交,就ok了
这里算是坑明白了 使用acos的时候要保证不能让大于1或者小于-1的数进来,因此加一个判断,在现场的时候就是这里被坑死了
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <string.h> using namespace std; const double epl =0.0000000001; const double PI=acos(-1.0); struct point{ double x,y; point(double a=0, double c=0){ x=a; y=c; } }; struct Circle{ point c; double r; point P(double a){ return point( (c.x+cos(a)*r) ,( c.y+sin(a)*r ) ); } }P1,P2,C1,C2; int dcmp(double x){ if(fabs(x)<epl) return 0; return x<0?-1:1; } double myz(double a){ if(dcmp(a+1.0)<=0) return acos(-1.0); if(dcmp(a-1.0)>=0) return acos(1.0); return acos(a); } point operator -(point A, point B){ return point(A.x-B.x,A.y-B.y); } bool operator ==(point A, point B){ return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0; } double Dot(point A, point B){ return A.x*B.x+A.y*B.y; } double length(point A){ return sqrt(Dot(A,A)); } double Angle(point A, point B){ return myz(Dot(A,B)/length(A)/length(B)); } double angle(point v){ return atan2(v.y,v.x); } int getdd(Circle C1, Circle C2, point &p1, point &p2){ double d=length(C1.c-C2.c); if(dcmp(d)==0){ return 0; } if(dcmp(C1.r+C2.r-d)<=0) return 1; if(dcmp(fabs(C1.r-C2.r)-d)>=0) return 0; double a=angle(C2.c-C1.c); double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d) ); p1= C1.P(a-da),p2=C1.P(a+da); if(p1==p2)return 1; return 2; } double Cross(point A, point B){ return A.x*B.y-A.y*B.x; } double Area(point A, point B, point C){ return fabs(Cross(B-A,C-A))/2; } double solve(Circle A, Circle B){ point pp1, pp2; int a=getdd(A,B,pp1,pp2); if(a==1) return 0; if(a==0) { double r=min(A.r,B.r); return r*r*PI; } if(dcmp(A.r-B.r)==0){ double a=Angle(pp1-A.c,pp2-A.c); double S=A.r*A.r*PI; double rate=a/(2*PI); double ans=S*rate-Area(A.c,pp1,pp2); return ans*2.0; }else{ if(A.r<B.r){ Circle te =A; A=B; B=te; } if(dcmp(Cross(pp1-pp2,A.c-pp2) )*dcmp(Cross(pp1-pp2,B.c-pp2))>=0 ){ double a1= Angle(pp1-A.c,pp2-A.c); double S1=A.r*A.r*PI; double rate1=a1/(2*PI); double ans1=S1*rate1-Area(A.c,pp1,pp2); double a2 = Angle(pp1-B.c,pp2-B.c); double S2 = B.r*B.r*PI; double rate2 = a2/(2*PI); double ans2=S2*rate2-Area(B.c,pp1,pp2); return S2-ans2+ans1; }else{ double a1= Angle(pp1-A.c,pp2-A.c); double S1=A.r*A.r*PI; double rate1=a1/(2*PI); double ans1=S1*rate1-Area(A.c,pp1,pp2); double a2 = Angle(pp1-B.c,pp2-B.c); double S2 = B.r*B.r*PI; double rate2 = a2/(2*PI); double ans2=S2*rate2-Area(B.c,pp1,pp2); return ans1+ans2; } } } int main() { int T; scanf("%d",&T); int cas=1; double x1,x2,y1,y2,r,R; while(T--){ scanf("%lf%lf",&r,&R); scanf("%lf%lf",&x1,&y1); scanf("%lf%lf",&x2,&y2); P1.c=point(x1,y1); P2.c=point(x1,y1); C1.c=point(x2,y2); C2.c=point(x2,y2); P1.r=C1.r=R; P2.r=C2.r=r; double dada=solve(P1,C1); double daxi=solve(P1,C2)*2; double xixi=solve(C2,P2); double ans=dada-daxi+xixi; printf("Case #%d: %.6lf ",cas++,ans); } return 0; }