HDU 5120 calcula el área de intersección de dos anillos

HDU 5120 Intersection
Matt es un gran admirador del diseño de logotipos. Recientemente se enamora del logo compuesto por anillos. Las siguientes figuras son algunos ejemplos famosos que quizás conozcas.

img
img

Un anillo es una figura 2-D delimitada por dos círculos que comparten el centro común. El radio de estos círculos se denota por r y R (r <R). Para obtener más detalles, consulte la parte gris en la siguiente ilustración.

img
img

Matt acaba de diseñar un nuevo logotipo que consta de dos anillos con el mismo tamaño en el plano 2D. Para sus intereses, a Matt le gustaría saber el área de la intersección de estos dos anillos.

Entrada

La primera línea contiene solo un número entero T (T ≤ 10 5), que indica el número de casos de prueba. Para cada caso de prueba, la primera línea contiene dos enteros r, R (0 ≤ r <R ≤ 10).

Cada una de las siguientes dos líneas contiene dos enteros xi, yi (0 ≤ xi, yi ≤ 20) que indican las coordenadas del centro de cada anillo.

Salida

Para cada caso de prueba, muestre una sola línea "Caso #x: y", donde x es el número de caso (a partir de 1) e y es el área de intersección redondeada a 6 decimales.

Entrada de muestra

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

Salida de muestra

Case #1: 15.707963
Case #2: 2.250778

Titulo

Para las muestras del grupo t, ingrese r, R para cada grupo de muestras, indicando los diámetros interno y externo del círculo, y luego proporcione las coordenadas del centro de los dos círculos para encontrar el área donde los dos círculos se cruzan

Encuentra el área donde se cruzan dos anillos

Conocimiento utilizado: teorema de seno y coseno, fórmula del área del sector, función trigonométrica inversa;

Hay una explicación detallada en el código ~

Gráfico

DREAM_yao
DREAM_yao

撸 Código:

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

Supongo que te gusta

Origin www.cnblogs.com/HappyKnockOnCode/p/12702813.html
Recomendado
Clasificación