HDU 5120 Intersection(几何模板题)

题意:给定两个圆环,求两个圆环相交的面积。

思路:由于圆心和半径不一样,分了好多种情况,后来发现只要把两个圆相交的函数写好之后就不需要那么复杂了。两个圆相交的面积的模板如下:

double area_of_overlap(point c1, double r1, point c2, double r2)
{
    double d = dist(c1, c2);
    if (sgn(d - r1 - r2) >= 0) return 0;
    if (sgn(fabs(r1 - r2) - d) >= 0)
    {
        double r = min(r1, r2);
        return PI * r * r;
    }
    double x = (d * d + r1 * r1 - r2 * r2) / (2.0 * d);
    double t1 = acos(x / r1);
    double t2 = acos((d - x) / r2);
    return r1 * r1 * t1 + r2 * r2 * t2 - d * r1 * sin(t1);
}

其实是求的这个面积:

完整代码如下:

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

using namespace std;
typedef long long ll;
const double eps = 1e-8;
const double PI = acos(0) * 2;
int sgn(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) {}
};
//获得两点的距离
double dist(const point &a, const point &b)
{
    double x = (a.x - b.x) * (a.x - b.x);
    double y = (a.y - b.y) * (a.y - b.y);
    return sqrt(x + y);
}
//求两个圆相交的面积,如果不相交返回0,c1为第一个圆心坐标,r1为第一个圆的半径,c2为第二个圆心坐标, r2为第二个圆的半径
double area_of_overlap(point c1, double r1, point c2, double r2)
{
    double d = dist(c1, c2);
    if (sgn(d - r1 - r2) >= 0) return 0;
    if (sgn(fabs(r1 - r2) - d) >= 0)
    {
        double r = min(r1, r2);
        return PI * r * r;
    }
    double x = (d * d + r1 * r1 - r2 * r2) / (2.0 * d);
    double t1 = acos(x / r1);
    double t2 = acos((d - x) / r2);
    return r1 * r1 * t1 + r2 * r2 * t2 - d * r1 * sin(t1);
}//下面此题求两个圆环相交的面积
int main()
{
    int T, kase = 0;
    point a, b;
    double r, R;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%lf %lf", &r, &R);
        scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y);
        double tot = area_of_overlap(a, R, b, R);
        double s1 = area_of_overlap(a, R, b, r);
        double s2 = area_of_overlap(a, r, b, r);
        printf("Case #%d: %.6f
", ++kase, tot - 2.0 * s1 + s2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Howe-Young/p/4833341.html