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;
}

猜你喜欢

转载自www.cnblogs.com/cold-cold/p/10082426.html