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