HDU 5120 计算两圆环相交面积

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

题意

给 t 组样例 ,每组样例输入r ,R ,表示圆的内径和外径,再给出两个圆的圆心坐标 ,求两圆环相交的面积

求两圆环相交面积

所用知识:正弦 、余弦定理 ,扇形面积公式,反三角函数;

代码中有详解哦~

图解

DREAM_yao
DREAM_yao

撸代码:

#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 ",++cnt,ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/HappyKnockOnCode/p/12702813.html