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


你可能感兴趣的:(HDU)