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

题意:给出一个圆的圆心坐标和半径,以及一个圆环的坐标和内外圆的半径,求这个圆和圆环的相交面积。

经分析可得,一共有如下几种情况:

ZOJ 3058 Circle and Ring(圆和圆环的相交面积)_第1张图片

通过计算可得出:

圆和圆环的相交面积 = 圆和圆环中大圆的相交面积 - 圆和圆环中小圆的相交面积。

参考代码:

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


你可能感兴趣的:(ZOJ 3058 Circle and Ring(圆和圆环的相交面积))