HDU 1798 Tell me the area (两圆相交面积)

来源:互联网 发布:仙侠网络 编辑:程序博客网 时间:2024/05/17 16:45

Tell me the area

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2527    Accepted Submission(s): 771

Problem Description
    There are two circles in the plane (shown in the below picture), there is a common area between the two circles. The problem is easy that you just tell me the common area.


Input
There are many cases. In each case, there are two lines. Each line has three numbers: the coordinates (X and Y) of the centre of a circle, and the radius of the circle.

Output
For each case, you just print the common area which is rounded to three digits after the decimal point. For more details, just look at the sample.

Sample Input
0 0 22 2 1
Sample Output
0.108
Author
wangye
Source
2008 “Insigma International Cup” Zhejiang Collegiate Programming Contest - Warm Up(4)

题解:
假设半径小的圆为c1,半径大的圆为c2。
c1的半径r1,圆心坐标(x1,y1)。c2的半径r2,圆心坐标(x2,y2)。
d为两圆圆心连线的长度。
相交面积为S
d=sqrt((x1-x2)^2+(y1-y2)^2)

(1)如果r1+r2<=d
那么两圆相离或外切,相交面积S=0

(2)如果r2-r1>=d
那么半径小的圆内含半径大的圆,那么相交面积为小圆的面积S=pi*r1*r1。

(3)既非(1)也非(2)
在图上画两个相交圆,结合图像看。
那么两圆相交,连接小圆的圆心与两个圆的交点,连接大圆的圆心和两个圆的交点。
可以发现形成的图形被两个圆心的连线平分成2个全等三角形。
由小圆圆心和交点所连两条线(长度为半径)以及在大圆之内的弧所形成的扇形为S1
由大圆圆心和交点所连两条线(长度为半径)以及在小圆之内的弧所形成的扇形为S2
由小圆圆心和交点所连两条线以及由大圆圆心和交点所连两条线所形成的四边形的面积为S3

可见相交面积S=S1+S2-S3

要求出扇形的面积,要知道扇形的圆心角。

小圆包含的扇形的圆心角为2*a1(考虑一个三角形)
a1=acos((r1^2+d^2-r2^2)/(2.0*r1*d)) 余弦定理
a2=acos((r2^2+d^2-r1^2)/(2.0*r2*d))
S1=pi*r1*r1*2*a1/(2*pi)=a1*r1*r1
同理
S2=a2*r2*r2
S3为一个三角形面积的2倍。(用海伦公式求三角形面积)

两个扇形面积减去两个三角形面积 等于阴影部分面积,即为两圆交叉重合部分面积.

AC代码: 
#include<algorithm>#include<iostream>#include<cmath>using namespace std;struct circle{  double x,y,r;};double dist(circle a,circle b){  return (double)sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int main(){circle a,b;double dis,p,area,a1,a2;double  s1,s2,s3;while(cin>>a.x>>a.y>>a.r>>b.x>>b.y>>b.r){dis=dist(a,b);double R=min(a.r,b.r);if(dis<=abs(a.r-b.r)) //内含或内切area=acos(-1.0)*R*R; else if(dis>=(a.r+b.r)) //外切或相离 area=0.0;else{    double p=(a.r+b.r+dis)/2.0;  a1=acos((a.r*a.r+dis*dis-b.r*b.r)/(2.0*a.r*dis));  a2=acos((b.r*b.r+dis*dis-a.r*a.r)/(2.0*b.r*dis));    s1=a1*a.r*a.r;    s2=a2*b.r*b.r;    s3=2*sqrt(p*(p-a.r)*(p-b.r)*(p-dis));  area=s1+s2-s3; }printf("%.3lf\n",area);  }return 0;}


1 0
原创粉丝点击