题意:两个内外径一样的环,给圆心坐标,求重叠部分的面积。
思路:圆面积求交+容斥。。直接上的模板,就是大圆交-2个大小圆交+小圆交。模板大法好啊。。
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
const double Pi=3.14159265358979323846;
double Rad2Deg(double rad){
return (rad*180.0/Pi);
}
double Deg2Rad(double deg){
return (deg*Pi/180.0);
}
double ArcCos(double val){
return Rad2Deg(acos(val));
}
double Sin(double deg){
return sin(Deg2Rad(deg));
}
struct CIRCLE{
double x;
double y;
double r;
CIRCLE(){}
CIRCLE(double xx,double yy,double rr){
x=xx; y=yy; r=rr;
}
};
struct POINT{
double x;
double y;
POINT():x(0),y(0){};
POINT(double xx,double yy):x(xx),y(yy){ }
};
double Distance(const POINT& a,const POINT& b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
POINT Center(const CIRCLE& circle){
return POINT(circle.x,circle.y);
}
double Area(const CIRCLE& circle){
return Pi*circle.r*circle.r;
}
double CommonArea(const CIRCLE& A,const CIRCLE &B){
double area=0.0;
const CIRCLE& M=(A.r>B.r)?A:B;
const CIRCLE& N=(A.r>B.r)?B:A;
double D=Distance(Center(M),Center(N));
if((D<M.r+N.r)&&(D>M.r-N.r)){
double cosM=(M.r*M.r+D*D-N.r*N.r)/(2.0*M.r*D);
double cosN=(N.r*N.r+D*D-M.r*M.r)/(2.0*N.r*D);
double alpha=2.0*ArcCos(cosM);
double beta=2.0*ArcCos(cosN);
double TM=0.5*M.r*M.r*Sin(alpha);
double TN=0.5*N.r*N.r*Sin(beta);
double FM=(alpha/360.0)*Area(M);
double FN=(beta/360.0)*Area(N);
area=FM+FN-TM-TN;
}else if(D<=M.r-N.r){
area=Area(N);
}
return area;
}
int main(){
int t;
cin>>t;
int cas=0;
while(t--){
cas++;
double r,R;
double x1,y1;
double x2,y2;
//cin>>r>>R>>x1>>y1>>x2>>y2;
scanf("%lf%lf%lf%lf%lf%lf",&r,&R,&x1,&y1,&x2,&y2);
CIRCLE cr1(x1,y1,r);
CIRCLE cr2(x2,y2,r);
CIRCLE cR1(x1,y1,R);
CIRCLE cR2(x2,y2,R);
double ans=CommonArea(cR1,cR2)+CommonArea(cr1,cr2);
ans-=CommonArea(cr1,cR2);
ans-=CommonArea(cR1,cr2);
printf("Case #%d: %.6lf\n",cas,ans);
}
return 0;
}