hdu 1098 Tell me the area

计算两圆相交面积

 

· d=sqrt((x1-x2)^2+(y1-y2)^2)

· (1)如果r1+r2<=d

· 那么两圆相离,相交面积S=0

· (2)如果r2-r1>=d

· 那么半径小的圆内含半径大的圆,那么相交面积为小圆的面积S=pi*r1*r1

· (3)两圆相交

· 那么两圆相交,连接小圆的圆心与两个圆的交点,连接大圆的圆心和两个圆的交点。

· 可以发现形成的图形被两个圆心的连线平分成2个全等三角形。

· 由小圆圆心和交点所连两条线(长度为半径)以及在大圆之内的弧所形成的扇形为S1

· 由大圆圆心和交点所连两条线(长度为半径)以及在小圆之内的弧所形成的扇形为S2

· 由小圆圆心和交点所连两条线以及由大圆圆心和交点所连两条线所形成的四边形的面积为S3

· 可见相交面积S=S1+S2-S3

· 要求出扇形的面积,要知道扇形的圆心角。

· 小圆包含的扇形的圆心角为2*a1(考虑一个三角形)

· a1=acos((r1^2+d^2-r2^2)/(2.0*r1*d)) 余弦定理

· a2=acos((r2^2+d^2-r1^2)/(2.0*r2*d)) 

· S1=pi*r1*r1*2*a1/(2*pi)=a1*r1*r1

· 同理

· S2=a2*r2*r2

· S3为一个三角形面积的2倍

· S3=2*r1*d*sin(a1)/2=r1*d*sin(a1)

· 则S=a1*r1*r1+a2*r2*r2-r1*d*sin(a1)

 

 

#include<iostream>
#include<cmath>
#include<iomanip>

using namespace std;

const double pi=acos(-1.0);

int main()
{
    double x1,y1,r1,x2,y2,r2;
    double d;
    double s,s1,s2,s3;
    double a1,a2;

    while(cin>>x1>>y1>>r1>>x2>>y2>>r2)
    {
        if(r1<r2)
        {
            swap(r1,r2);
            swap(x1,x2);
            swap(y1,y2);
        }

        d=sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) );

        if(d>=r1+r2)
            cout<<0.000<<endl;
        else if(d <= r1-r2 )
        {
            cout<<fixed<<setprecision(3)<<pi*r2*r2<<endl;
        }
        else
        {
            double t=0.5*(r1+r2+d);

            a1=acos( (r1*r1 + d*d - r2*r2) / (2*r1*d) );
            a2=acos( (r2*r2 + d*d - r1*r1) / (2*r2*d) );

            s1=r1*r1*a1;
            s2=r2*r2*a2;
//         这样精度不够: s3= sin(a1)*r1*d;
            s3=2*sqrt( t * (t-r1) * (t-r2) * (t-d) );

            s=s1+s2-s3;

            cout<<fixed<<setprecision(3)<<s<<endl;
        }
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值