HDU 5120 calculates the intersection area of two rings

HDU 5120 Intersection
Matt is a big fan of logo design. Recently he falls in love with logo made up by rings. The following figures are some famous examples you may know.

img
img

A ring is a 2-D figure bounded by two circles sharing the common center. The radius for these circles are denoted by r and R (r < R). For more details, refer to the gray part in the illustration below.

img
img

Matt just designed a new logo consisting of two rings with the same size in the 2-D plane. For his interests, Matt would like to know the area of the intersection of these two rings.

Input

The first line contains only one integer T (T ≤ 10 5), which indicates the number of test cases. For each test case, the first line contains two integers r, R (0 ≤ r < R ≤ 10).

Each of the following two lines contains two integers x i, y i(0 ≤ x i, y i ≤ 20) indicating the coordinates of the center of each ring.

Output

For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y is the area of intersection rounded to 6 decimal places.

Sample Input

2
2 3
0 0
0 0
2 3
0 0
5 0

Sample Output

Case #1: 15.707963
Case #2: 2.250778

Title

For the samples of group t, enter r, R for each group of samples, indicating the inner and outer diameters of the circle, and then give the coordinates of the center of the two circles to find the area where the two circles intersect

Find the area where two rings intersect

Knowledge used: theorem of sine and cosine, formula of sector area, inverse trigonometric function;

There is a detailed explanation in the code ~

Graphic

DREAM_yao
DREAM_yao

撸 Code:

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
const double PI = acos(-1),eps=1e-8;
struct Circle
{

    double x,y,r;
};
double getDis(Circle a,Circle b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double area(Circle a,Circle b)/*求任意两圆相交面积*/
{
    /*在这里浮点数的比较我不用 ==  ,用eps */
    double dis =getDis(a,b) ;
    if(dis+min(a.r,b.r)-max(a.r,b.r)<=eps)/*内含或重合*/
    {
        if(a.r-b.r<eps)
            return PI*a.r*a.r;
        else
            return PI*b.r*b.r;
    }
    else if(dis-(a.r+b.r)>=eps)/*相切或相离*/
    {
        return 0.0;
    }
    else /*相交*/
    {
        /*余弦定理求圆心角*/
        double a1 = 2 * acos((a.r*a.r + dis*dis - b.r*b.r)/(2*a.r*dis));
        double b1 = 2 * acos((b.r*b.r + dis*dis - a.r*a.r)/(2*b.r*dis));

        /*两圆分别用圆心角求扇形面积,再减去三角形面积,求和*/
        double area1 = a.r*a.r*a1/2-a.r*a.r*sin(a1)/2;/* (1/2)*r*L - (1/2)* a*b*sin(c)*/
        double area2 = b.r*b.r*b1/2-b.r*b.r*sin(b1)/2;
        return area1+area2;
    }
}
int main()
{
    int cnt=0,Case;
    double r,R;
    double x1,y1,x2,y2;
    Circle a,b,A,B;
    scanf("%d",&Case);
    while(Case--)
    {
        scanf("%lf%lf",&r,&R);
        a.r=b.r=r;
        A.r=B.r=R;

        scanf("%lf%lf",&a.x,&a.y);
        A.x=a.x,A.y=a.y;

        scanf("%lf%lf",&b.x,&b.y);
        B.x=b.x,B.y=b.y;
        double ans=area(A,B)-area(A,b)-area(B,a)+area(a,b);
        printf("Case #%d: %.6f\n",++cnt,ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/HappyKnockOnCode/p/12702813.html