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\n", ++kase, tot - 2.0 * s1 + s2); } return 0; }