/******************************************************************************
* Compilation: javac Rectangle.java
* Execution: none
*
* Immutable data type for axis-aligned rectangle.
*
******************************************************************************/
/**
* The {@code Rectangle} class is an immutable data type to encapsulate a
* two-dimensional axis-aligned rectagle with real-value coordinates.
* The rectangle is closed—it includes the points on the boundary.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public final class Rectangle {
private final double xmin, ymin; // minimum x- and y-coordinates
private final double xmax, ymax; // maximum x- and y-coordinates
/**
* Initializes a new rectangle [xmin, xmax]
* x [ymin, ymax].
*
* @param xmin the x-coordinate of the lower-left endpoint
* @param xmax the x-coordinate of the upper-right endpoint
* @param ymin the y-coordinate of the lower-left endpoint
* @param ymax the y-coordinate of the upper-right endpoint
* @throws IllegalArgumentException if any of {@code xmin},
* {@code xmax}, {@code ymin}, or {@code ymax}
* is {@code Double.NaN}.
* @throws IllegalArgumentException if {@code xmax < xmin} or {@code ymax < ymin}.
*/
public Rectangle(double xmin, double ymin, double xmax, double ymax) {
if (Double.isNaN(xmin) || Double.isNaN(xmax))
throw new IllegalArgumentException("x-coordinate cannot be NaN");
if (Double.isNaN(ymin) || Double.isNaN(ymax))
throw new IllegalArgumentException("y-coordinates cannot be NaN");
if (xmax < xmin || ymax < ymin) {
throw new IllegalArgumentException("Invalid rectangle");
}
this.xmin = xmin;
this.ymin = ymin;
this.xmax = xmax;
this.ymax = ymax;
}
/**
* Returns the minimum x-coordinate of any point in this rectangle.
*
* @return the minimum x-coordinate of any point in this rectangle
*/
public double xmin() {
return xmin;
}
/**
* Returns the maximum x-coordinate of any point in this rectangle.
*
* @return the maximum x-coordinate of any point in this rectangle
*/
public double xmax() {
return xmax;
}
/**
* Returns the minimum y-coordinate of any point in this rectangle.
*
* @return the minimum y-coordinate of any point in this rectangle
*/
public double ymin() {
return ymin;
}
/**
* Returns the maximum y-coordinate of any point in this rectangle.
*
* @return the maximum y-coordinate of any point in this rectangle
*/
public double ymax() {
return ymax;
}
/**
* Returns the width of this rectangle.
*
* @return the width of this rectangle {@code xmax - xmin}
*/
public double width() {
return xmax - xmin;
}
/**
* Returns the height of this rectangle.
*
* @return the height of this rectangle {@code ymax - ymin}
*/
public double height() {
return ymax - ymin;
}
/**
* Returns true if the two rectangles intersect.
*
* @param that the other rectangle
* @return {@code true} if this rectangle intersect the argument
rectagnle at one or more points, including on the boundary
*/
public boolean intersects(Rectangle that) {
return this.xmax >= that.xmin && this.ymax >= that.ymin
&& that.xmax >= this.xmin && that.ymax >= this.ymin;
}
/**
* Returns true if this rectangle contain the rectangle.
* @param rect the rectangle
* @return {@code true} if this rectangle contain the rectangle {@code rect},
possibly at the boundary; {@code false} otherwise
*/
public boolean contains(Rectangle rect) {
return (rect.xmin >= xmin) && (rect.xmax <= xmax)
&& (rect.ymin >= ymin) && (rect.ymax <= ymax);
}
/**
* Compares this rectangle to the specified rectangle.
*
* @param other the other rectangle
* @return {@code true} if this rectangle equals {@code other};
* {@code false} otherwise
*/
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (other == null) return false;
if (other.getClass() != this.getClass()) return false;
Rectangle that = (Rectangle) other;
if (this.xmin != that.xmin) return false;
if (this.ymin != that.ymin) return false;
if (this.xmax != that.xmax) return false;
if (this.ymax != that.ymax) return false;
return true;
}
/**
* Returns an integer hash code for this rectangle.
* @return an integer hash code for this rectangle
*/
@Override
public int hashCode() {
int hash1 = ((Double) xmin).hashCode();
int hash2 = ((Double) ymin).hashCode();
int hash3 = ((Double) xmax).hashCode();
int hash4 = ((Double) ymax).hashCode();
return 31*(31*(31*hash1 + hash2) + hash3) + hash4;
}
/**
* Returns a string representation of this rectangle.
*
* @return a string representation of this rectangle, using the format
* {@code [xmin, xmax] x [ymin, ymax]}
*/
@Override
public String toString() {
return "[" + xmin + ", " + xmax + "] x [" + ymin + ", " + ymax + "]";
}
/**
* Draws this rectangle to standard draw.
*/
public void draw() {
StdDraw.line(xmin, ymin, xmax, ymin);
StdDraw.line(xmax, ymin, xmax, ymax);
StdDraw.line(xmax, ymax, xmin, ymax);
StdDraw.line(xmin, ymax, xmin, ymin);
}
}