Circular Area
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5763 | Accepted: 2255 |
Description
Your task is to write a program, which, given two circles, calculates the area of their intersection with the accuracy of three digits after decimal point.
Input
In the single line of input file there are space-separated real numbers x1 y1 r1 x2 y2 r2. They represent center coordinates and radii of two circles.
Output
The output file must contain single real number - the area.
Sample Input
20.0 30.0 15.0 40.0 30.0 30.0
Sample Output
608.366
Source
Northeastern Europe 2000, Far-Eastern Subregion
题意:求两个圆的公共面积
两圆相交求公共弦长公式:
已知两个圆的半径,两个圆心的距离,在相交情况下
假设两个半径分别是a,b,圆心距是c
那么公共弦的长度是--------sqrt((a+b+c)(a+b-c)(a+c-b)(b+c-a))/c
(a+b+c)(a+b-c)(a+c-b)(b+c-a)的乘积开根号,然后再除以c
海伦公式:
S=sqrt(p(p-a)(p-b)(p-c))
#include<iostream>
#include<cstdio>
#include<cmath>
const double pi=acos(-1.0);
struct POINT
{
double x;
double y;
POINT():x(0),y(0) {};
POINT(double _x_,double _y_):x(_x_),y(_y_) {};
};
struct Circular
{
POINT O;
double r;
};
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));
}
double pub_area(double r,double pub_ch) //通过扇形面积减去三角形面积求公共面积(有两部分)
{
double p=0.5*(r+r+pub_ch);
double S_tri=sqrt(p*(p-r)*(p-r)*(p-pub_ch)); //海伦公式计算三角形面积
double angle=acos((2*r*r-pub_ch*pub_ch)/(2*r*r)); //通过余弦定理计算出公共弦对应的圆心角(acos()函数计算出来的值为弧度制)
double S_sector=0.5*angle*r*r; //计算出扇形面积
return S_sector-S_tri;
}
bool isAcute_angle(double r1,double r2,double o_dis) //判断是不是锐角
{
return acos((r2*r2+o_dis*o_dis-r1*r1)/(2*r2*o_dis))<pi/2;
}
int main()
{
//freopen("in.txt","r",stdin);
Circular a,b;
while(~scanf("%lf%lf%lf%lf%lf%lf",&a.O.x,&a.O.y,&a.r,&b.O.x,&b.O.y,&b.r))
{
bool ar_min=true;
double maxn_r;
if(a.r>b.r)
{
ar_min=false;
maxn_r=a.r;
}
else
{
maxn_r=b.r;
}
double O_dis=Distance(a.O,b.O);
double pub_chord=sqrt((a.r+b.r+O_dis)*(a.r+b.r-O_dis)*(a.r+O_dis-b.r)*(b.r+O_dis-a.r))/O_dis; //公共弦长
if(a.r>=b.r&&a.r>=b.r+O_dis) //圆b在圆a内
{
printf("%.3f\n",b.r*b.r*pi);
continue;
}
if(b.r>a.r&&b.r>=a.r+O_dis)
{
printf("%.3f\n",a.r*a.r*pi);
continue;
}
if(O_dis>=a.r+b.r) //两圆不相交
{
printf("0.000\n");
continue;
}
if(maxn_r>O_dis) //两圆相交时
{
if(ar_min&&isAcute_angle(b.r,a.r,O_dis))
{
printf("%.3f\n",pub_area(a.r,pub_chord)+pub_area(b.r,pub_chord));
}
if(!ar_min&&isAcute_angle(a.r,b.r,O_dis))
{
printf("%.3f\n",pub_area(a.r,pub_chord)+pub_area(b.r,pub_chord));
}
if(ar_min&&!isAcute_angle(b.r,a.r,O_dis))
{
printf("%.3f\n",a.r*a.r*pi-(pub_area(a.r,pub_chord)-pub_area(b.r,pub_chord)));
}
if(!ar_min&&!isAcute_angle(a.r,b.r,O_dis))
{
printf("%.3f\n",b.r*b.r*pi-(pub_area(b.r,pub_chord)-pub_area(a.r,pub_chord)));
}
}
else
{
printf("%.3f\n",pub_area(a.r,pub_chord)+pub_area(b.r,pub_chord));
}
}
return 0;
}