您的位置:首页 > 其它

ZOJ 3058 Circle and Ring(圆和圆环的相交面积)

2015-04-04 12:50 375 查看
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 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: