Advertisement
PloadyFree

Geometry (temp)

Dec 15th, 2018
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.55 KB | None | 0 0
  1. package net.egork;
  2.  
  3. import net.egork.io.InputReader;
  4. import net.egork.io.OutputWriter;
  5.  
  6. public class Task674 {
  7.     public void solve(int testNumber, InputReader in, OutputWriter out) {
  8.         Circle c1 = Circle.read(in);
  9.         Circle c2 = Circle.read(in);
  10.         double area = c1.intersectionArea(c2);
  11.         out.printFormat("%.20f", area);
  12.     }
  13.  
  14.     static double hypot(double dx, double dy) {
  15.         return Math.sqrt(dx * dx + dy * dy);
  16.     }
  17.  
  18.     static class Point {
  19.         double x, y;
  20.  
  21.         Point(double x, double y) {
  22.             this.x = x;
  23.             this.y = y;
  24.         }
  25.  
  26.         double distance(Point p) {
  27.             double dx = p.x - x;
  28.             double dy = p.y - y;
  29.             return hypot(dx, dy);
  30.         }
  31.  
  32.         static Point read(InputReader in) {
  33.             double x = in.readDouble();
  34.             double y = in.readDouble();
  35.             return new Point(x, y);
  36.         }
  37.  
  38.         static double angle(Point a, Point b, Point o) {
  39.             double angleA = Math.atan2(a.y - o.y, a.x - o.x);
  40.             double angleB = Math.atan2(b.y - o.y, b.x - o.x);
  41.             double angle = angleA - angleB;
  42.             while (angle < 0) angle += 2 * Math.PI;
  43.             while (angle >= 2 * Math.PI) angle -= 2 * Math.PI;
  44.             return angle;
  45.         }
  46.  
  47.         @Override
  48.         public String toString() {
  49.             return "Point{" +
  50.                     "x=" + x +
  51.                     ", y=" + y +
  52.                     '}';
  53.         }
  54.     }
  55.  
  56.     static class Circle {
  57.         Point center;
  58.         double radius;
  59.  
  60.         Circle(Point center, double radius) {
  61.             this.center = center;
  62.             this.radius = radius;
  63.         }
  64.  
  65.         double area() {
  66.             return Math.PI * radius * radius;
  67.         }
  68.  
  69.         double sector(double angle) {
  70.             return area() * angle / (2 * Math.PI);
  71.         }
  72.  
  73.         double triangle(double angle) {
  74.             return radius * radius * Math.sin(angle) / 2;
  75.         }
  76.  
  77.         double segment(double angle) {
  78.             return sector(angle) - triangle(angle);
  79.         }
  80.  
  81.         double intersectionArea(Circle other) {
  82.             if (radius > other.radius)
  83.                 return other.intersectionArea(this);
  84.  
  85.             if (center.distance(other.center) + radius <= other.radius)
  86.                 return area();
  87.  
  88.             if (center.distance(other.center) >= radius + other.radius)
  89.                 return 0;
  90.  
  91.             Line line = new Line(this, other);
  92.             Point[] intersections = line.intersection(this);
  93.  
  94.             double angle1 = Point.angle(intersections[0], intersections[1], center);
  95.             double angle2 = Point.angle(intersections[1], intersections[0], other.center);
  96.             if (angle2 > Math.PI) {
  97.                 angle1 = 2 * Math.PI - angle1;
  98.                 angle2 = 2 * Math.PI - angle2;
  99.             }
  100.             double area1 = segment(angle1);
  101.             double area2 = other.segment(angle2);
  102.  
  103.             return area1 + area2;
  104.         }
  105.  
  106.         static Circle read(InputReader in) {
  107.             Point center = Point.read(in);
  108.             double radius = in.readDouble();
  109.             return new Circle(center, radius);
  110.         }
  111.  
  112.         @Override
  113.         public String toString() {
  114.             return "Circle{" +
  115.                     "center=" + center +
  116.                     ", radius=" + radius +
  117.                     '}';
  118.         }
  119.     }
  120.  
  121.     static class Line {
  122.         double a, b, c;
  123.  
  124.         Line(double a, double b, double c) {
  125.             this.a = a;
  126.             this.b = b;
  127.             this.c = c;
  128.             normalize();
  129.         }
  130.  
  131.         Line(Circle c1, Circle c2) {
  132.             double x1 = c1.center.x;
  133.             double y1 = c1.center.y;
  134.             double r1 = c1.radius;
  135.             double x2 = c2.center.x;
  136.             double y2 = c2.center.y;
  137.             double r2 = c2.radius;
  138.             a = 2 * (x2 - x1);
  139.             b = 2 * (y2 - y1);
  140.             c = +
  141.                     (x1 * x1 - x2 * x2) +
  142.                     (y1 * y1 - y2 * y2) +
  143.                     (r2 * r2 - r1 * r1);
  144.             normalize();
  145.         }
  146.  
  147.         void normalize() {
  148.             double h = hypot(-b, a);
  149.             a = a / h;
  150.             b = b / h;
  151.             c = c / h;
  152.         }
  153.  
  154.         Line perpendicular(Point p) {
  155.             return new Line(-b, a, b * p.x - a * p.y);
  156.         }
  157.  
  158.         Point intersection(Line other) {
  159.             double a1 = a;
  160.             double b1 = b;
  161.             double c1 = c;
  162.             double a2 = other.a;
  163.             double b2 = other.b;
  164.             double c2 = other.c;
  165.             double x = (b2 * c1 - b1 * c2) / (a2 * b1 - a1 * b2);
  166.             double y = (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1);
  167.             return new Point(x, y);
  168.         }
  169.  
  170.         Point[] intersection(Circle circle) {
  171.             Line perpendicular = perpendicular(circle.center);
  172.             Point intersection = intersection(perpendicular);
  173.             double len = intersection.distance(circle.center);
  174.             double shift = Math.sqrt(circle.radius * circle.radius - len * len);
  175.             return new Point[] {
  176.                     new Point(intersection.x - b * shift, intersection.y + a * shift),
  177.                     new Point(intersection.x + b * shift, intersection.y - a * shift)
  178.             };
  179.         }
  180.  
  181.         @Override
  182.         public String toString() {
  183.             return "Line{" +
  184.                     "a=" + a +
  185.                     ", b=" + b +
  186.                     ", c=" + c +
  187.                     '}';
  188.         }
  189.     }
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement