hdu5120Intersection+圆环的面积交

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值