POJ 2546 - Circular Area
http://poj.org/problem?id=2546
概要
2つの円の中心座標と半径がそれぞれ与えられるので,共通部分の面積を答える.
制約
- 出力は 10^-3 の精度
解法
がんばって計算する.
poj/2546.cc1 #include <cstdio> 2 #include <complex> 3 #include <cmath> 4 using namespace std; 5 typedef complex<double> P; 6 static const double PI = atan2(+0.0, -0.0); 7 static const double EPS = 1e-6; 8 9 inline double cross(const P& a, const P& b) 10 { 11 return a.real()*b.imag() - b.real()*a.imag(); 12 } 13 14 struct segment 15 { 16 P a, b; 17 segment() {} 18 segment(const P& x, const P& y) : a(x), b(y) {} 19 inline double distance(const P& p) const 20 { 21 return abs(cross(p - a, b - a)) / abs(b - a); 22 } 23 inline double length() const { return abs(b - a); } 24 inline P intersect(const segment& seg) const 25 { 26 const double d1 = seg.distance(a); 27 const double d2 = seg.distance(b); 28 const double t = d1 / (d1 + d2); 29 return (1-t)*a + t*b; 30 } 31 }; 32 33 struct circle 34 { 35 P o; 36 double r; 37 circle() {} 38 circle(const P& o_, double r_) : o(o_), r(r_) {} 39 40 inline double area() const { return PI*r*r; } 41 double intersection_area(const circle& c) const 42 { 43 const double d = abs(c.o - o); 44 //if (d > r + c.r) { 45 if (r + c.r - d < EPS) { 46 return 0.0; 47 //} else if (d < abs(r - c.r)) { 48 } else if (d - abs(r - c.r) < EPS) { 49 const double r1 = min(r, c.r); 50 return r1*r1*PI; 51 } else { 52 const double cos_ = (d*d + r*r - c.r*c.r) / (2*d); 53 const double theta = acos(cos_ / r); 54 const double phi = acos((d - cos_) / c.r); 55 return r*r*theta + c.r*c.r*phi - d*r*sin(theta); 56 } 57 } 58 }; 59 60 int main() 61 { 62 double x1, y1, r1, x2, y2, r2; 63 scanf("%lf %lf %lf %lf %lf %lf\n", &x1, &y1, &r1, &x2, &y2, &r2); 64 const circle c1(P(x1, y1), r1), c2(P(x2, y2), r2); 65 printf("%.3f\n", c1.intersection_area(c2)); 66 return 0; 67 }