CF600D Area of Two Circles' Intersection
题意:
分别给出两个圆的圆心坐标和半径((x1,y1),r1和(x2,y2),r2),求两个圆相交部分的面积。
两个圆的关系,可分为三种情况,相离,相交,包含
1.相离或边缘重合,输出0即可
2.包含的话输出小圆的面积即可
3.相交的话
如上图,总面积等于SACC1=S扇形DCC1A-SΔDCC1A
所以我们用余弦定理求出∠D即可求出总面积
计算时要用long double
实现如下:
#include <algorithm> #include <iostream> #include <cmath> #include <cstring> #include <map> #include <string> #include <vector> #include <queue> #include <stack> #include <cstdio> #include <cstdlib> using namespace std; typedef long long ll; typedef long double ld; inline int read() { register int p(1),a(0);register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') p=-1,ch=getchar(); while(ch>='0'&&ch<='9') a=a*10+ch-48,ch=getchar(); return a*p; } const ld pai=atan2(0,-1); ld suan(ld a,ld c,ld b) { ld jiao=acos((a*a+b*b-c*c)/a/b/2)*2; return a*a*(jiao-sin(jiao))/2; } int main() { // freopen("input","r",stdin); // freopen("output","w",stdout); ld x1,y1,x2,y2,r1,r2,dis; x1=read(),y1=read(),r1=read(); x2=read(),y2=read(),r2=read(); if(r1>r2) swap(x1,x2),swap(y1,y2),swap(r1,r2); dis=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); if(r1+r2<=dis) printf("0.00000000000000000000"); else if(r1+dis<=r2) printf("%.20lf",(double)(r1*r1*pai)); else printf("%.20lf",(double)(suan(r1,r2,dis)+suan(r2,r1,dis))); return 0; }