Given a circle and a ring, your task is to calculate the area of their intersection.
Input
This problem contains multiple test cases, process to the end of file.
For each case, there are two lines. The first line contains three real numbers x', y' and r' (0 <= r' <= 1024) representing the circle. The second line contains four real numbers x, y, rand R (0 <= r <= R <= 1024) representing the ring.
Output
For each case, output the area with the accuracy of three digits after decimal point in a signal line.
Never output "-0.000"!
Sample Input
10 0 20 -10 0 10 20 20 30 15 40 30 0 30
Sample Output
351.041
608.366
題意:給出一個圓的圓心座標和半徑,以及一個圓環的座標和內外圓的半徑,求這個圓和圓環的相交面積。
經分析可得,一共有如下幾種情況:
通過計算可得出:
圓和圓環的相交面積 = 圓和圓環中大圓的相交面積 - 圓和圓環中小圓的相交面積。
參考代碼:
#include <cstdio>
#include <cmath>
using namespace std;
#define PI acos(-1.0) //定義PI
struct Circle { // 定義圓
double x, y;
double r;
};
struct Ring { // 定義圓環
double x, y;
double r, R;
};
struct Get_Intersection_Circle_Ring {
//求圓心距,即兩個圓心之間的距離
double get_dis(double x1, double y1, double x2, double y2) {
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
// 求兩圓的相交面積
double get_CircleIntersectionArea(Circle c1, Circle c2) {
double dis = get_dis(c1.x, c1.y, c2.x, c2.y);
// 圓心距大於半徑和,兩圓相交面積爲0
if(dis >= c1.r + c2.r) return 0;
double min_r = c1.r < c2.r ? c1.r : c2.r;
double max_r = c1.r > c2.r ? c1.r : c2.r;
if(min_r + dis <= max_r) //圓心距小於半徑之差,兩圓包含關係
return PI * min_r * min_r;
double a = acos((c1.r * c1.r + dis * dis - c2.r * c2.r) / 2 / c1.r / dis);
double b = acos((c2.r * c2.r + dis * dis - c1.r * c1.r) / 2 / c2.r / dis);
double area1 = a * c1.r * c1.r; //第一個圓中扇形的面積, 弧長L=a*c1.r,面積等於0.5*L*c1.r
double area2 = b * c2.r * c2.r; //第二個圓中扇形的面積
double ans = area1 + area2; //兩個扇形的面積和等於四邊形的面積加上兩圓相交的面積
double area_qua = sin(a) * c1.r * dis; //四邊形的面積
ans -= area_qua;
return ans;
}
//求圓和圓環的相交面積
double Get_IntersectionArea(Circle C, Ring R) {
Circle temp1, temp2;
temp1.x = R.x, temp1.y = R.y, temp1.r = R.R;
temp2.x = R.x, temp2.y = R.y, temp2.r = R.r;
return get_CircleIntersectionArea(C, temp1) - get_CircleIntersectionArea(C, temp2);
}
};
int main()
{
Circle c;
Ring r;
Get_Intersection_Circle_Ring x;
while(~scanf("%lf%lf%lf", &c.x, &c.y, &c.r)) {
scanf("%lf%lf%lf%lf", &r.x, &r.y, &r.r, &r.R);
printf("%.3lf\n", x.Get_IntersectionArea(c, r));
}
return 0;
}