天天看点

hdu 5120 Intersection(几何 容斥)hdu 5120 Intersection

hdu 5120 Intersection

(a1 - b1) X (a2 - b2)  = a1Xa2 - b1Xa2 - a1Xb2 + b1Xb2
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const double eps = 1e-8;
const double PI = acos(-1.0);
struct _node
{
    double x, y, r;
    _node(double xx = 0.0, double yy  = 0.0, double rr = 0.0):x(xx),y(yy),r(rr) {}
    double dis(const _node & a)
    {
        return sqrt((x-a.x)*(x-a.x) + (y-a.y)*(y-a.y));
    }
};
inline int zero(double x)
{
    return (x>eps) - (x<-eps);
}
double cal(_node a, _node b)    // 求两圆相交面积
{
    double d = a.dis(b), r1=a.r, r2=b.r;
    double a1, a2;
    if (r1 > r2) swap(r1, r2);
    if (zero(d - (r1+r2)) >= 0)
        return 0.0;
    if (zero(d - (r2 - r1)) <= 0)
        return PI*r1*r1;
    a1=acos((r1*r1+d*d-r2*r2)/(2.0*r1*d));
    a2=acos((r2*r2+d*d-r1*r1)/(2.0*r2*d));
    return (a1*r1*r1+a2*r2*r2-r1*d*sin(a1));
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int t;
    double rr, r;
    double x1, x2, y1, y2;
    scanf("%d", &t);
    for (int _ =1; _ <= t; ++_)
    {
        printf("Case #%d: ", _);
        scanf("%lf%lf", &r, &rr);
        scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
        printf("%.6lf\n", cal(_node(x1,y1,rr), _node(x2,y2,rr)) -
               cal(_node(x1,y1,rr), _node(x2,y2,r)) -
               cal(_node(x1,y1,r), _node(x2,y2,rr)) +
               cal(_node(x1,y1,r), _node(x2,y2,r)));
    }
    return 0;
}