86 lines
3.2 KiB
Java
86 lines
3.2 KiB
Java
import java.util.Objects;
|
|
|
|
public class Circles {
|
|
private static class Point {
|
|
private final double x, y;
|
|
|
|
public Point(Double x, Double y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
|
|
public double distanceFrom(Point other) {
|
|
double dx = x - other.x;
|
|
double dy = y - other.y;
|
|
return Math.sqrt(dx * dx + dy * dy);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object other) {
|
|
if (this == other) return true;
|
|
if (other == null || getClass() != other.getClass()) return false;
|
|
Point point = (Point) other;
|
|
return x == point.x && y == point.y;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return String.format("(%.4f, %.4f)", x, y);
|
|
}
|
|
}
|
|
|
|
private static Point[] findCircles(Point p1, Point p2, double r) {
|
|
if (r < 0.0) throw new IllegalArgumentException("the radius can't be negative");
|
|
if (r == 0.0 && p1 != p2) throw new IllegalArgumentException("no circles can ever be drawn");
|
|
if (r == 0.0) return new Point[]{p1, p1};
|
|
if (Objects.equals(p1, p2)) throw new IllegalArgumentException("an infinite number of circles can be drawn");
|
|
double distance = p1.distanceFrom(p2);
|
|
double diameter = 2.0 * r;
|
|
if (distance > diameter) throw new IllegalArgumentException("the points are too far apart to draw a circle");
|
|
Point center = new Point((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0);
|
|
if (distance == diameter) return new Point[]{center, center};
|
|
double mirrorDistance = Math.sqrt(r * r - distance * distance / 4.0);
|
|
double dx = (p2.x - p1.x) * mirrorDistance / distance;
|
|
double dy = (p2.y - p1.y) * mirrorDistance / distance;
|
|
return new Point[]{
|
|
new Point(center.x - dy, center.y + dx),
|
|
new Point(center.x + dy, center.y - dx)
|
|
};
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
Point[] p = new Point[]{
|
|
new Point(0.1234, 0.9876),
|
|
new Point(0.8765, 0.2345),
|
|
new Point(0.0000, 2.0000),
|
|
new Point(0.0000, 0.0000)
|
|
};
|
|
Point[][] points = new Point[][]{
|
|
{p[0], p[1]},
|
|
{p[2], p[3]},
|
|
{p[0], p[0]},
|
|
{p[0], p[1]},
|
|
{p[0], p[0]},
|
|
};
|
|
double[] radii = new double[]{2.0, 1.0, 2.0, 0.5, 0.0};
|
|
for (int i = 0; i < radii.length; ++i) {
|
|
Point p1 = points[i][0];
|
|
Point p2 = points[i][1];
|
|
double r = radii[i];
|
|
System.out.printf("For points %s and %s with radius %f\n", p1, p2, r);
|
|
try {
|
|
Point[] circles = findCircles(p1, p2, r);
|
|
Point c1 = circles[0];
|
|
Point c2 = circles[1];
|
|
if (Objects.equals(c1, c2)) {
|
|
System.out.printf("there is just one circle with center at %s\n", c1);
|
|
} else {
|
|
System.out.printf("there are two circles with centers at %s and %s\n", c1, c2);
|
|
}
|
|
} catch (IllegalArgumentException ex) {
|
|
System.out.println(ex.getMessage());
|
|
}
|
|
System.out.println();
|
|
}
|
|
}
|
|
}
|