ZOJ 3058 Circle and Ring(圓和圓環的相交面積)

Circle and Ring

Time Limit: 1 Second      Memory Limit: 32768 KB

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章