Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package net.egork;
- import net.egork.io.InputReader;
- import net.egork.io.OutputWriter;
- public class Task674 {
- public void solve(int testNumber, InputReader in, OutputWriter out) {
- Circle c1 = Circle.read(in);
- Circle c2 = Circle.read(in);
- double area = c1.intersectionArea(c2);
- out.printFormat("%.20f", area);
- }
- static double hypot(double dx, double dy) {
- return Math.sqrt(dx * dx + dy * dy);
- }
- static class Point {
- double x, y;
- Point(double x, double y) {
- this.x = x;
- this.y = y;
- }
- double distance(Point p) {
- double dx = p.x - x;
- double dy = p.y - y;
- return hypot(dx, dy);
- }
- static Point read(InputReader in) {
- double x = in.readDouble();
- double y = in.readDouble();
- return new Point(x, y);
- }
- static double angle(Point a, Point b, Point o) {
- double angleA = Math.atan2(a.y - o.y, a.x - o.x);
- double angleB = Math.atan2(b.y - o.y, b.x - o.x);
- double angle = angleA - angleB;
- while (angle < 0) angle += 2 * Math.PI;
- while (angle >= 2 * Math.PI) angle -= 2 * Math.PI;
- return angle;
- }
- @Override
- public String toString() {
- return "Point{" +
- "x=" + x +
- ", y=" + y +
- '}';
- }
- }
- static class Circle {
- Point center;
- double radius;
- Circle(Point center, double radius) {
- this.center = center;
- this.radius = radius;
- }
- double area() {
- return Math.PI * radius * radius;
- }
- double sector(double angle) {
- return area() * angle / (2 * Math.PI);
- }
- double triangle(double angle) {
- return radius * radius * Math.sin(angle) / 2;
- }
- double segment(double angle) {
- return sector(angle) - triangle(angle);
- }
- double intersectionArea(Circle other) {
- if (radius > other.radius)
- return other.intersectionArea(this);
- if (center.distance(other.center) + radius <= other.radius)
- return area();
- if (center.distance(other.center) >= radius + other.radius)
- return 0;
- Line line = new Line(this, other);
- Point[] intersections = line.intersection(this);
- double angle1 = Point.angle(intersections[0], intersections[1], center);
- double angle2 = Point.angle(intersections[1], intersections[0], other.center);
- if (angle2 > Math.PI) {
- angle1 = 2 * Math.PI - angle1;
- angle2 = 2 * Math.PI - angle2;
- }
- double area1 = segment(angle1);
- double area2 = other.segment(angle2);
- return area1 + area2;
- }
- static Circle read(InputReader in) {
- Point center = Point.read(in);
- double radius = in.readDouble();
- return new Circle(center, radius);
- }
- @Override
- public String toString() {
- return "Circle{" +
- "center=" + center +
- ", radius=" + radius +
- '}';
- }
- }
- static class Line {
- double a, b, c;
- Line(double a, double b, double c) {
- this.a = a;
- this.b = b;
- this.c = c;
- normalize();
- }
- Line(Circle c1, Circle c2) {
- double x1 = c1.center.x;
- double y1 = c1.center.y;
- double r1 = c1.radius;
- double x2 = c2.center.x;
- double y2 = c2.center.y;
- double r2 = c2.radius;
- a = 2 * (x2 - x1);
- b = 2 * (y2 - y1);
- c = +
- (x1 * x1 - x2 * x2) +
- (y1 * y1 - y2 * y2) +
- (r2 * r2 - r1 * r1);
- normalize();
- }
- void normalize() {
- double h = hypot(-b, a);
- a = a / h;
- b = b / h;
- c = c / h;
- }
- Line perpendicular(Point p) {
- return new Line(-b, a, b * p.x - a * p.y);
- }
- Point intersection(Line other) {
- double a1 = a;
- double b1 = b;
- double c1 = c;
- double a2 = other.a;
- double b2 = other.b;
- double c2 = other.c;
- double x = (b2 * c1 - b1 * c2) / (a2 * b1 - a1 * b2);
- double y = (a2 * c1 - a1 * c2) / (a1 * b2 - a2 * b1);
- return new Point(x, y);
- }
- Point[] intersection(Circle circle) {
- Line perpendicular = perpendicular(circle.center);
- Point intersection = intersection(perpendicular);
- double len = intersection.distance(circle.center);
- double shift = Math.sqrt(circle.radius * circle.radius - len * len);
- return new Point[] {
- new Point(intersection.x - b * shift, intersection.y + a * shift),
- new Point(intersection.x + b * shift, intersection.y - a * shift)
- };
- }
- @Override
- public String toString() {
- return "Line{" +
- "a=" + a +
- ", b=" + b +
- ", c=" + c +
- '}';
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement