hdu1798——计算几何——计算两圆相交面积

这篇博客介绍了一个C++程序,用于计算两个圆相交时的面积。程序首先判断两圆的位置关系,包括相离、外切、内切、内含和相交,然后根据位置关系计算相应的面积。对于相交情况,程序使用余弦定理来确定圆心角并计算相交部分的面积。代码中包含了详细的注释,便于理解。
摘要由CSDN通过智能技术生成

入门难度,老规矩,先上链接🔗

题目包含多组测试数据,每组测试数据占两行,每行3个整数,分别是圆心坐标和半径

我们在计算面积之前要确定两圆的位置关系,因此先判断两半径的和与两圆心相距的大小。

不扯淡了,直接上代码,注释超级完善

代码如下

#include<iostream>
#include<cmath>
#define PI acos(-1)
using namespace std;
struct Point
{
    double x,y,R;
    Point(double x=0,double y=0,double R=0):x(x),y(y),R(R){}
};
//虽然不知道为什么这里的半径要用double来表示,估计是为了提高精度吧。注意最后输出的是3位小数
//计算两圆心之间的长度
//圆与圆之间的位置关系分为:相离(R1+R2>l),外切(R1+R2==l),在这道题目中,前两种的面积都是0,相交满足情况(R1+R2>l>fabs(R1-R2)),还有内切满足(fabs(R1-R2)==l),最后一种就是内含了,满足(fabs(R1-R2)>l),在这道题中内切和内含的面积都是小圆的面积。


//题目思路:先读取数据,然后计算圆心距,判断两圆的位置关系,最后输出结果

double long_circle(Point,Point);

int main()
{
    Point R1,R2;
    double x,y,R;
    while(~scanf("%lf %lf %lf",&x,&y,&R)){
        R1.x=x,R1.y=y,R1.R=R;
        scanf("%lf %lf %lf",&x,&y,&R);
        R2.x=x,R2.y=y,R2.R=R;
        double l=long_circle(R1,R2);
        if(l>=(R1.R+R2.R)){//相离以及外切的情况
            printf("0.000\n");
        }else if(l<=fabs(R1.R-R2.R)){//内切或者内含的情况
            if(R1.R<R2.R){
                printf("%.3lf\n",PI*R1.R*R1.R);
            }else{
                printf("%.3lf\n",PI*R2.R*R2.R);
            }
        }else{//最复杂的相交情况,使用余弦定理计算三角形的面积,因为我们已知两条半径,还有圆心距,这就构成了一个三角形
            //先求出圆心角,根据余弦定理有a^2+b^2-c^/2*a*b
            double degree1=2*acos((R1.R*R1.R+l*l-R2.R*R2.R)/(2*R1.R*l));//R1的圆心角
            double degree2=2*acos((R2.R*R2.R+l*l-R1.R*R1.R)/(2*R2.R*l));//R2的圆心角
            //得到圆心角之后我们就可以计算三角形的面积和扇形的面积了
            //扇形面积公式S=1/2*a*R*R,此处的a是圆心角,弧度制
            double s1=degree1/2*R1.R*R1.R;
            double s2=degree2/2*R2.R*R2.R;
            //求三角形面积用面积公式s=1/2*a*b*sinc;
            double t1=R1.R*R1.R*sin(degree1)/2;
            double t2=R2.R*R2.R*sin(degree2)/2;
            //最后把扇形面积相加再减去两个三角形就是我我们所求的面积了
            double s=s1+s2-t1-t2;
            printf("%.3lf\n",s);
        }
    }
    system("pause");
    return 0;
}


double long_circle(Point A,Point B)
{
    return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值