001package algs32.kdtree; 002import algs12.Point2D; 003import stdlib.*; 004 005/* *********************************************************************** 006 * Compilation: javac RectHV.java 007 * Execution: java RectHV 008 * Dependencies: Point2D.java 009 * 010 * Implementation of 2D axis-aligned rectangle. 011 * 012 *************************************************************************/ 013 014public class RectHV { 015 private final double xmin, ymin; // minimum x- and y-coordinates 016 private final double xmax, ymax; // maximum x- and y-coordinates 017 018 // construct the axis-aligned rectangle (xmin, ymin) x (xmax, ymax) 019 public RectHV(double xmin, double ymin, double xmax, double ymax) { 020 this.xmin = xmin; 021 this.ymin = ymin; 022 this.xmax = xmax; 023 this.ymax = ymax; 024 if (xmax < xmin || ymax < ymin) { 025 throw new IllegalArgumentException("Invalid rectangle: " + this); 026 } 027 } 028 029 // accessor methods for 4 coordinates 030 public double xmin() { return xmin; } 031 public double ymin() { return ymin; } 032 public double xmax() { return xmax; } 033 public double ymax() { return ymax; } 034 035 // width and height of rectangle 036 public double width() { return xmax - xmin; } 037 public double height() { return ymax - ymin; } 038 039 // does this axis-aligned rectangle intersect that one? 040 public boolean intersects(RectHV that) { 041 return this.xmax >= that.xmin && this.ymax >= that.ymin 042 && that.xmax >= this.xmin && that.ymax >= this.ymin; 043 } 044 045 // draw this axis-aligned rectangle 046 public void draw() { 047 StdDraw.line(xmin, ymin, xmax, ymin); 048 StdDraw.line(xmax, ymin, xmax, ymax); 049 StdDraw.line(xmax, ymax, xmin, ymax); 050 StdDraw.line(xmin, ymax, xmin, ymin); 051 } 052 053 // distance from p to closest point on this axis-aligned rectangle 054 public double distanceTo(Point2D p) { 055 return Math.sqrt(this.distanceSquaredTo(p)); 056 } 057 058 // distance squared from p to closest point on this axis-aligned rectangle 059 public double distanceSquaredTo(Point2D p) { 060 double dx = 0.0, dy = 0.0; 061 if (p.x() < xmin) dx = p.x() - xmin; 062 else if (p.x() > xmax) dx = p.x() - xmax; 063 if (p.y() < ymin) dy = p.y() - ymin; 064 else if (p.y() > ymax) dy = p.y() - ymax; 065 return dx*dx + dy*dy; 066 } 067 068 // does this axis-aligned rectangle contain p? 069 public boolean contains(Point2D p) { 070 return (p.x() >= xmin) && (p.x() <= xmax) 071 && (p.y() >= ymin) && (p.y() <= ymax); 072 } 073 074 // are the two axis-aligned rectangles equal? 075 public boolean equals(Object y) { 076 if (y == this) return true; 077 if (y == null) return false; 078 if (y.getClass() != this.getClass()) return false; 079 final RectHV that = (RectHV) y; 080 if (this.xmin != that.xmin) return false; 081 if (this.ymin != that.ymin) return false; 082 if (this.xmax != that.xmax) return false; 083 if (this.ymax != that.ymax) return false; 084 return true; 085 } 086 087 private int hashCode = 0; 088 public int hashCode() { 089 int hCode = hashCode; 090 if (hCode != 0) 091 return hCode; 092 int result = 17; 093 result = 37*result + Double.hashCode (xmin); 094 result = 37*result + Double.hashCode (xmax); 095 result = 37*result + Double.hashCode (ymin); 096 result = 37*result + Double.hashCode (ymax); 097 hashCode = result; 098 return result; 099 } 100 101 // return a string representation of this axis-aligned rectangle 102 public String toString() { 103 return "(" + xmin + ", " + ymin + ") x (" + xmax + ", " + ymax + ")"; 104 } 105 106}