package rescuecore2.misc.geometry.spatialindex; import static rescuecore2.misc.geometry.spatialindex.Tools.equal; import rescuecore2.misc.geometry.Point2D; import rescuecore2.misc.geometry.Line2D; import rescuecore2.misc.geometry.GeometryTools2D; /** A line region. */ public class LineRegion implements Region { private double x1; private double y1; private double x2; private double y2; private Line2D line; /** Construct a line region. @param x1 The first X coordinate. @param y1 The first Y coordinate. @param x2 The second X coordinate. @param y2 The second Y coordinate. */ public LineRegion(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; line = null; } /** Get the first X coordinate. @return The first X coordinate. */ public double getX1() { return x1; } /** Get the first Y coordinate. @return The first Y coordinate. */ public double getY1() { return y1; } /** Get the second X coordinate. @return The second X coordinate. */ public double getX2() { return x2; } /** Get the second Y coordinate. @return The second Y coordinate. */ public double getY2() { return y2; } /** Get a Line2D representing this region. @return A Line2D representation of the region. */ public Line2D getLine() { if (line == null) { line = new Line2D(new Point2D(x1, y1), new Point2D(x2, y2)); } return line; } @Override public double getXMin() { return Math.min(x1, x2); } @Override public double getYMin() { return Math.min(y1, y2); } @Override public double getXMax() { return Math.max(x1, x2); } @Override public double getYMax() { return Math.max(y1, y2); } @Override public boolean equals(Object o) { if (o instanceof LineRegion) { LineRegion l = (LineRegion)o; return equal(x1, l.x1) && equal(y1, l.y1) && equal(x2, l.x2) && equal(y2, l.y2); } return false; } @Override public int hashCode() { Double d = x1 + x2 + y1 + y2; return d.hashCode(); } @Override public String toString() { return "Line region: " + x1 + ", " + y1 + " -> " + x2 + ", " + y2; } @Override public boolean intersects(Region r) { if (r instanceof RectangleRegion) { RectangleRegion rect = (RectangleRegion)r; return GeometryTools2D.clipToRectangle(getLine(), rect.getXMin(), rect.getYMin(), rect.getXMax(), rect.getYMax()) != null; } else if (r instanceof LineRegion) { LineRegion l = (LineRegion)r; return GeometryTools2D.getSegmentIntersectionPoint(getLine(), l.getLine()) != null; } else if (r instanceof PointRegion) { PointRegion p = (PointRegion)r; return GeometryTools2D.contains(getLine(), p.getPoint()); } else { return false; } } @Override public boolean contains(Region r) { if (r instanceof LineRegion) { LineRegion l = (LineRegion)r; double first = GeometryTools2D.positionOnLine(getLine(), l.getLine().getOrigin()); double second = GeometryTools2D.positionOnLine(getLine(), l.getLine().getEndPoint()); return first >= 0 && first <= 1 && second >= 0 && second <= 1; } else if (r instanceof PointRegion) { PointRegion p = (PointRegion)r; double d = GeometryTools2D.positionOnLine(getLine(), p.getPoint()); return d >= 0 && d <= 1; } return false; } /* @Override public boolean touches(Region r) { if (r instanceof RectangleRegion) { RectangleRegion rect = (RectangleRegion)r; return (equal(this.x, rect.getXMin()) || equal(this.x, rect.getXMax()) || equal(this.y, rect.getYMin()) || equal(this.y, rect.getYMax())); } else if (r instanceof PointRegion) { PointRegion p = (PointRegion)r; return (equal(this.x, p.x) || equal(this.y, p.y)); } else if (r instanceof NullRegion) { return false; } else { throw new IllegalArgumentException("Cannot check for touch with " + r); } } */ }