1626: 计算面积
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 73 Solved: 33
[ Submit][ Status][ Web Board]
Description
给定两个全等的圆环,求其相交的面积。
Input
第一行输入一个 T,表示有T组数据。
输入圆环的内径和外径,r , R (0<=r<R<=10)。
输入两个圆环的坐标xi,yi。(xi,yi<=20)
Output
求两圆环相交的面积
Sample Input
2
2 3
0 0
0 0
2 3
0 0
5 0
Sample Output
Case #1: 15.707963
Case #2: 2.250778
【解析】
此处借鉴他人的代码,附上自己的理解。这道题叫我们求的其实就是两个圆环实体相交的面积。
也就是说我们要求的是红色部分的面积,我们把右边那个圆定义成圆B,里面小圆定义成b,左边那个圆定义成圆A,
里面的小圆定义成
圆a。我们只需要让A和B相交的面积减去B和a相交的面积然后再减去A和b相交的面积这个时候其实
a和b相交的面积已经多减去了1个,所以我们还要再加上a和b相交的面积。也就是area(A,B)-area(B-a)-area(A,b)+
area(a,b)。这里要注意的是我们怎么求相交的面积。我们可以先求圆心角,然后求出扇形的面积再减去三角形的面积
其实就可以求出相交的面积了。这里求圆心角用到的是余弦定理。如下图所示。我们要把角A求出来。这里总共有两个
扇形面积要减去三角形面积加起来就是相交的面积了。就是三角形BCD对应的扇形减去三角形BCD这个的面积,另外一
边也是类似。我们通过三角形ABC可以求出角A的角度。扇形的面积公式就是所对应的圆心角为a面积就是(1/2)*a*r*r
#include <iostream>
#include <cmath>
#include<cstdio>
#include<cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const double PI = acos(-1);//计算PI的值
struct circle {
double x;
double y;
double r;
};
double facs(circle a, circle b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double area(circle a, circle b) {
double len,jiao1,jiao2,area1,area2,area;
if((facs(a, b)+min(a.r,b.r))<=max(a.r,b.r))//此处表示内含或者重合了
{
if(a.r<b.r)
return PI*a.r*a.r;
else
return PI*b.r*b.r;
}
else if(facs(a, b)>=(a.r+b.r))//这里是相切或者相离了
return 0;
else
{
len=facs(a, b);
jiao1=2*acos((a.r*a.r+len*len-b.r*b.r)/(2*a.r*len));//计算圆心角,这里用到了反余弦比如说acos(1/2)就是60度的意思
jiao2=2*acos((b.r*b.r+len*len-a.r*a.r)/(2*b.r*len));
area1=a.r*a.r*jiao1/2-a.r*a.r*sin(jiao1)/2;
area2=b.r*b.r*jiao2/2-b.r*b.r*sin(jiao2)/2;
area=area1+area2;
return area;
}
}
int main()
{
circle A,a,B,b;
int t;
double r, R,sum;
scanf("%d", &t) ;
for(int i=1; i<=t; i++)
{
scanf("%lf%lf", &r, &R);
a.r = b.r = r;
A.r = B.r = R;
scanf("%lf%lf", &a.x, &a.y);
A.x = a.x;
A.y = a.y;
scanf("%lf%lf", &b.x, &b.y);
B.x = b.x;
B.y = b.y;
sum = area(A,B)-area(B,a)-area(A,b)+area(a, b);
printf("Case #%d: %.6f\n", i,sum);
}
return 0;
}