Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <cmath>
- #include <functional>
- #include <cassert>
- #include <cstdint>
- #include <algorithm>
- typedef long double Real;
- const Real PI = std::acos(-1.0L);
- Real solve(Real x1, Real y1, Real r1, Real x2, Real y2, Real r2) {
- assert(r1 >= r2);
- Real dist2 = (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
- if (dist2 >= (r1+r2)*(r1+r2)) { // Если пересечений нет - ответ 0
- return 0;
- }
- // Если меньший круг лежит внутри большего: r1 >= dist + r2
- if ((r1-r2)*(r1-r2) >= dist2) {
- return PI * r2 * r2;
- }
- std::function<Real(Real, Real, Real)> angle = [](Real a, Real b, Real c) {
- // Вычисление угла angle напротив стороны a по теореме косинусов
- // a^2 = b^2+c^2-2*b*c*cos(alpha)
- return std::acos((b*b+c*c-a*a) / b / c / 2);
- };
- std::function<Real(Real, Real)> S = [](Real r, Real angle) {
- // площадь сектора минус площадь треугольника
- // r - радиус круга, angle - угол между сторонами сектора
- return r * r * (angle / 2 - std::sin(angle) / 2);
- };
- Real dist = std::sqrt(dist2); // расстояние между центрами окружностей
- Real alpha = 2 * angle(r2, r1, dist); // угол при большей окружности
- Real beta = 2 * angle(r1, r2, dist); // угол при меньшей окружности
- return S(r1, alpha) + S(r2, beta);
- }
- int main() {
- // freopen("input.txt", "rt", stdin);
- Real x1, y1, r1, x2, y2, r2;
- std::cin >> x1 >> y1 >> r1;
- std::cin >> x2 >> y2 >> r2;
- if (r1 < r2) {
- std::swap(x1, x2);
- std::swap(y1, y2);
- std::swap(r1, r2);
- }
- std::cout << std::fixed << std::setprecision(6) << solve(x1, y1, r1, x2, y2, r2) << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement