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

本文介绍了一个算法,用于计算给定圆心坐标、半径的圆与给定内外圆半径的圆环的相交面积。通过解析不同情况下的几何关系,实现了精确的面积计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值