package com.github.davidmoten.rtree.geometry; import static com.github.davidmoten.rtree.geometry.Geometries.point; import com.github.davidmoten.guavamini.Objects; import com.github.davidmoten.guavamini.Optional; import com.github.davidmoten.rtree.internal.util.ObjectsHelper; public final class Circle implements Geometry { private final float x, y, radius; private final Rectangle mbr; protected Circle(float x, float y, float radius) { this.x = x; this.y = y; this.radius = radius; this.mbr = RectangleImpl.create(x - radius, y - radius, x + radius, y + radius); } static Circle create(double x, double y, double radius) { return new Circle((float) x, (float) y, (float) radius); } static Circle create(float x, float y, float radius) { return new Circle(x, y, radius); } public float x() { return x; } public float y() { return y; } public float radius() { return radius; } @Override public Rectangle mbr() { return mbr; } @Override public double distance(Rectangle r) { return Math.max(0, point(x, y).distance(r) - radius); } @Override public boolean intersects(Rectangle r) { return distance(r) == 0; } public boolean intersects(Circle c) { double total = radius + c.radius; return point(x, y).distanceSquared(point(c.x, c.y)) <= total * total; } @Override public int hashCode() { return Objects.hashCode(x, y, radius); } @Override public boolean equals(Object obj) { Optional<Circle> other = ObjectsHelper.asClass(obj, Circle.class); if (other.isPresent()) { return Objects.equal(x, other.get().x) && Objects.equal(y, other.get().y) && Objects.equal(radius, other.get().radius); } else return false; } public boolean intersects(Point point) { return Math.sqrt(sqr(x - point.x()) + sqr(y - point.y())) <= radius; } private float sqr(float x) { return x * x; } public boolean intersects(Line line) { return line.intersects(this); } }