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 ≤ 10^5), 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
Source
2014ACM/ICPC亚洲区北京站-重现赛(感谢北师和上交)
Recommend
liuyiding
给两个一样大小的圆环。位置不一样。求两个圆环的面积交
其实就是容斥加圆的面积交。外圆的面积交-大圆与内圆的面积交(2个)+内圆的面积交
这里被自己的模板坑了。以前的模板都是保证相交的,这里的圆的面积交可以是相离、包含的,要自己再判一下。(罚时两发,orz)。。
#include<bits/stdc++.h>
#define pi acos(-1.0)
using namespace std;
#define eps 1e-8
struct point {
double x,y;
point(){};
point(double x,double y):x(x),y(y){};
};
double dis(const point &a,const point &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct Circle {
point p;
double r;
Circle(){};
Circle(point p,double r):p(p),r(r){};
};
double Circle_area(Circle x,Circle y){
double a=dis(x.p,y.p),b=x.r,c=y.r;
//相离、相切
if(a>=b+c) return 0.0;
//某个圆是点时
if(b<eps||c<eps) return 0.0;
//包含
if(b<c) swap(b,c);
if(a+c<=b) return pi*c*c;
//相交。
double cta1=acos((a*a+b*b-c*c)/2/(a*b)),
cta2=acos((a*a+c*c-b*b)/2/(a*c));
double s1=b*b*cta1-b*b*sin(cta1)*(a*a+b*b-c*c)/2/(a*b);
double s2=c*c*cta2-c*c*sin(cta2)*(a*a+c*c-b*b)/2/(a*c);
return fabs(s1+s2);
}
int main(){
int t;
//cout<<Circle_area(Circle(point(0,0),2),Circle(point(0,1),2));
scanf("%d",&t);
for(int cas=1;cas<=t;cas++){
double r1,r2;
double x1,y1,x2,y2;
scanf("%lf %lf",&r2,&r1);
scanf("%lf %lf",&x1,&y1);
scanf("%lf %lf",&x2,&y2);
Circle a1=Circle(point(x1,y1),r1);
Circle a2=Circle(point(x1,y1),r2);
Circle a3=Circle(point(x2,y2),r1);
Circle a4=Circle(point(x2,y2),r2);
double ans=Circle_area(a1,a3);
ans-=Circle_area(a1,a4);
ans-=Circle_area(a2,a3);
ans+=Circle_area(a2,a4);
printf("Case #%d: %.6f\n",cas,ans);
}
return 0;
}