UVALive 7066 Intersection(圆环相交面积)

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

原文地址:https://www.cnblogs.com/caomingpei/p/9709522.html