Problem Description
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.
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.
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 ≤ 105), 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 xi, yi (0 ≤ xi, yi ≤ 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.
input
2
2 3
0 0
0 0
2 3
0 0
5 0
output
Case #1: 15.707963
Case #2: 2.250778
主要就是大圆与大圆相交的面积-2*大圆与小圆相交的面积
+小圆与小圆相交的面积
#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define M 3.14159265358
using namespace std;
const double esp=1e-10;
double mianji(double r1,double r2,double d)
{
if ( r1+r2 <= d )
return 0;
else if ( r1-r2 >= d )
return M*r2*r2;
double p=(r1+r2+d)/2;
double sa=acos((r1*r1+d*d-r2*r2)/(2*r1*d));
double sb=acos((r2*r2+d*d-r1*r1)/(2*r2*d));
double area=sa*r1*r1+sb*r2*r2-2*sqrt(p*(p-r1)*(p-r2)*(p-d));
return area;
}
int main()
{
int t;
int x1,x2,y1,y2;
int r1,r2;
while ( ~scanf("%d",&t) )
{
int ma, ma1;
for ( int i = 1; i <= t; i++ )
{
scanf("%d%d",&ma,&ma1);
r1 = min(ma, ma1);
r2 = max(ma, ma1);
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
double d=sqrt((x1-x2)*(x1-x2)*1.0+1.0*(y1-y2)*(y1-y2));
double sum1 = mianji(r2*1.0,r2*1.0,d);
double sum2 = mianji(r2*1.0,r1*1.0,d);
double sum3 = mianji(r1*1.0,r1*1.0,d);
double sum = sum1-2*sum2+sum3;
printf ( "Case #%d: %.6f\n",i, sum );
}
}
return 0;
}