UVALive 7066 Intersection
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.
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
题解
题意
两个圆环,给出大圆和小圆半径,以及两个圆的圆心位置。求交叉部分的面积
思路
其实割补法,大圆和大圆的交叉-2*小圆和大圆的交叉+小圆和小圆的交叉。
注意:求交叉面积时注意写法。注意判断是否相离
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const long double PI = acos(-1.0);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
int T;
typedef long double ld;
#define zero(x) (((x)>0?(x):-(x))<eps)
ld r,R;
struct Node{
ld x;
ld y;
};
Node a,b;
ld dis(Node a,Node b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
ld calcir(Node a,Node b,ld r1,ld r2){
ld cd = dis(a,b);
if(abs(cd)<eps) return PI*max(r1,r2)*max(r1,r2);
if((cd-(r1+r2))>eps) return -1;
if(abs(cd-(r1+r2))<eps) return 0;
if(min(r1,r2)+cd<=max(r1,r2)) return PI*min(r1,r2)*min(r1,r2);
ld A1=2*acos((r1*r1+cd*cd-r2*r2)/(2*r1*cd));
ld A2=2*acos((r2*r2+cd*cd-r1*r1)/(2*r2*cd));
ld s1=0.5*r1*r1*sin(A1)+0.5*r2*r2*sin(A2);
ld s2=A1/2*r1*r1+A2/2*r2*r2;
return s2-s1;
}
int main() {
int T;
scanf("%d",&T);
int kase= 0;
while(T--){
kase++;
scanf("%Lf %Lf",&r,&R);
scanf("%Lf %Lf",&a.x,&a.y);
scanf("%Lf %Lf",&b.x,&b.y);
ld ans = 0;
ld jud1 = calcir(a,b,R,R);
ld jud2 = calcir(a,b,r,R);
ld jud3 = calcir(a,b,R,r);
ld jud4 = calcir(a,b,r,r);
if(jud1!=-1) ans += jud1;
if(jud2!=-1) ans -= jud2;
if(jud3!=-1) ans -= jud3;
if(jud4!=-1) ans += jud4;
//printf("jud:%Lf %Lf %Lf %Lf
",jud1,jud2,jud3,jud4);
printf("Case #%d: %.6Lf
",kase,abs(ans));
}
return 0;
}