首页 > 代码库 > HDOJ 5120 Intersection 两圆面积交

HDOJ 5120 Intersection 两圆面积交


两圆面积交....

Intersection

Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 101    Accepted Submission(s): 38


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.
 

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亚洲区北京站-重现赛(感谢北师和上交)
 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;

const double eps=1e-8;

int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return (x<0)?-1:1;
}

struct Point
{
    double x,y;
    Point(double _x=0,double _y=0):x(_x),y(_y) {};
};

Point operator+(Point A,Point B)
{
    return Point(A.x+B.x,A.y+B.y);
}
Point operator-(Point A,Point B)
{
    return Point(A.x-B.x,A.y-B.y);
}
Point operator*(Point A,double p)
{
    return Point(A.x*p,A.y*p);
}
Point operator/(Point A,double p)
{
    return Point(A.x/p,A.y/p);
}

bool operator<(const Point&a,const Point&b)
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}

bool operator==(const Point&a,const Point&b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}

double Dot(Point A,Point B)
{
    return A.x*B.x+A.y*B.y;
}
double Length(Point A)
{
    return sqrt(Dot(A,A));
}
double Angle(Point A,Point B)
{
    return acos(Dot(A,B)/Length(A)/Length(B));
}
double Angle(Point v)
{
    return atan2(v.y,v.x);
}
double Cross(Point A,Point B)
{
    return A.x*B.y-A.y*B.x;
}

///圆
const double pi=acos(-1.0);

struct Circle
{
    Point c;
    double r;
    Circle(Point _c=0,double _r=0):c(_c),r(_r) {}
    Point point(double a)///根据圆心角算圆上的点
    {
        return Point(c.x+cos(a)*r,c.y+sin(a)*r);
    }
};

double R,r;
Point O1,O2;

/// 两圆的面积交
double Circle_Circle_Area_of_overlap(Circle c1, Circle c2)
{
    double d=Length(c1.c-c2.c);
    if(dcmp(c1.r+c2.r-d)<=0) return 0.;
    if(dcmp(fabs(c1.r-c2.r)-d)>=0)
    {
        double minr = min(c1.r,c2.r);
        return pi*minr*minr;
    }
    double x=(d*d + c1.r*c1.r - c2.r*c2.r)/(2*d);
    double t1=acos(x/c1.r);
    double t2=acos((d-x)/c2.r);
    return c1.r*c1.r*t1 + c2.r*c2.r*t2 - d*c1.r*sin(t1);
}

int main()
{
    int T_T,cas=1;
    scanf("%d",&T_T);
    while(T_T--)
    {
        scanf("%lf%lf%lf%lf%lf%lf",&r,&R,&O1.x,&O1.y,&O2.x,&O2.y);

        Circle Dayuan1(O1,R);
        Circle Dayuan2(O2,R);
        Circle Xiaoyuan1(O1,r);
        Circle Xiaoyuan2(O2,r);

        double areaDD=Circle_Circle_Area_of_overlap(Dayuan1,Dayuan2);
        double areaXX=Circle_Circle_Area_of_overlap(Xiaoyuan1,Xiaoyuan2);
        double areaDX=Circle_Circle_Area_of_overlap(Dayuan1,Xiaoyuan2);
        double areaXD=Circle_Circle_Area_of_overlap(Xiaoyuan1,Dayuan2);

        printf("Case #%d: %.6lf\n",cas++,areaDD-areaDX-areaXD+areaXX);
    }
    return 0;
}




HDOJ 5120 Intersection 两圆面积交