```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}

```