Advertisement
dmkozyrev

Untitled

Apr 24th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.07 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <cmath>
  4. #include <functional>
  5. #include <cassert>
  6.  
  7. using namespace std;
  8.  
  9. typedef int64_t Int;
  10. typedef long double Real;
  11.  
  12. const Real PI = std::acos(-1.0L);
  13.  
  14. Real solve(Int x1, Int y1, Int r1, Int x2, Int y2, Int r2) {
  15.     assert(r1 >= r2);
  16.     Int dist2 = (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
  17.    
  18.     if (dist2 >= (r1+r2)*(r1+r2)) { // пересечений нет
  19.         return 0;
  20.     }
  21.     // r1 >= dist + r2 - площадь меньшего круга
  22.     if ((r1-r2)*(r1-r2) >= dist2) {
  23.         return PI * r2 * r2;
  24.     }
  25.     Real dist = std::sqrt(Real(dist2));
  26.    
  27.     // r2^2 = r1^2 + d^2 - 2 * b * d * cos(alpha)
  28.     // r2^2 - r1^2 - d^2 = - 2 * r1 * d * cos(alpha)
  29.     // acos((-r2^2 + r1^2 + d^2) / r1 / d / 2)
  30.     std::function<Real(Int, Int, Int)> angle = [](Int a, Int b, Int c) {
  31.         // a^2 = b^2+d^2-2*b*d*cos(alpha)
  32.         Real cos_alpha = Real(b*b+c*c-a*a) / b / c / 2;
  33.         cos_alpha = std::min(cos_alpha,  1.0L);
  34.         cos_alpha = std::max(cos_alpha, -1.0L);
  35.         return std::acos(cos_alpha);
  36.     };
  37.        
  38.     if (r1 * r1 >= dist2 + r2 * r2) { // угол тупой
  39.         //std::cout << "two" << std::endl;
  40.         Real alpha = angle(r1, r2, dist);
  41.         Real beta = angle(r2, r1, dist);
  42.         //assert(2*alpha >= PI);
  43.         Real s_triangle = dist * r2 * std::sin(alpha) / 2;
  44.         Real S1 = r2 * r2 * alpha;
  45.         Real S2 = r1 * r1 * beta - 2 * s_triangle;
  46.         //cout << "S1 = " << S1 << ", S2 = " << S2 << endl;
  47.         return S1 + S2;
  48.     } else {
  49.         Real alpha = angle(r2, r1, dist);
  50.         Real beta = angle(r1, r2, dist);
  51.         // sin(a) = c / r1
  52.         // c = 2 * r1 * sin(a)
  53.         return alpha * r1 * r1 + beta * r2 * r2 - dist * r1 * std::sin(alpha);
  54.     }
  55. }
  56.  
  57. int main() {
  58.     //freopen("input.txt", "rt", stdin);
  59.    
  60.     Int x1, y1, r1, x2, y2, r2;
  61.     cin >> x1 >> y1 >> r1;
  62.     cin >> x2 >> y2 >> r2;
  63.    
  64.     if (r1 < r2) {
  65.         swap(x1, x2);
  66.         swap(y1, y2);
  67.         swap(r1, r2);
  68.     }
  69.    
  70.     cout << fixed << setprecision(8) << solve(x1, y1, r1, x2, y2, r2) << endl;
  71.    
  72.     return 0;
  73. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement