1 package org.djutils.quadtree; 2 3 import java.io.Serializable; 4 5 import org.djutils.exceptions.Throw; 6 7 /** 8 * Rectangle defines an area bounded by a lower and left edges (inclusive) and a upper and right edges (not inclusive). The 9 * boundary values are stored in the object; unlike the Rectangle2D class where the width and height are stored and to the left 10 * and bottom. Doing it this way absolutely ensures that we can make a grid of rectangles that have no ULP width gaps. 11 * Additionally, this Rectangle object is immutable. Finally, there is no annoying name collision with the java.lang.Double 12 * class.<br> 13 * <br> 14 * Copyright (c) 2020-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See 15 * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is 16 * distributed under a three-clause BSD-style license, which can be found at 17 * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>. <br> 18 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a> 19 * @author <a href="https://www.tudelft.nl/pknoppers">Peter Knoppers</a> 20 */ 21 public class Rectangle implements Serializable 22 { 23 /** ... */ 24 private static final long serialVersionUID = 20200904L; 25 26 /** Left boundary (inclusive). */ 27 private final double left; 28 29 /** Bottom boundary (inclusive). */ 30 private final double bottom; 31 32 /** Right boundary (not inclusive). */ 33 private final double right; 34 35 /** Top boundary (not inclusive). */ 36 private final double top; 37 38 /** 39 * Construct a new Rectangle; all arguments are checked for having sensible values. 40 * @param left double; the left boundary (inclusive) 41 * @param bottom double; the bottom boundary (inclusive) 42 * @param right double; the right boundary (not inclusive) 43 * @param top double; the top boundary (not inclusive) 44 * @param check boolean; if true; the values are checked for making sense 45 */ 46 public Rectangle(final double left, final double bottom, final double right, final double top, final boolean check) 47 { 48 this(left, bottom, right, top); 49 if (check) 50 { 51 Throw.when(Double.isNaN(left), IllegalArgumentException.class, "The value of left may not be NaN"); 52 Throw.when(Double.isNaN(bottom), IllegalArgumentException.class, "The value of bottom may not be NaN"); 53 Throw.when(Double.isNaN(right), IllegalArgumentException.class, "The value of right may not be NaN"); 54 Throw.when(Double.isNaN(top), IllegalArgumentException.class, "The value of top may not be NaN"); 55 Throw.when(left > right, IllegalArgumentException.class, "The value of left may not exceed the value of right"); 56 Throw.when(bottom > top, IllegalArgumentException.class, "The value of bottom may not exceed the value of top"); 57 } 58 } 59 60 /** 61 * Construct a new Rectangle without checking the arguments for making sense. 62 * @param left double; the left boundary (inclusive) 63 * @param bottom double; the bottom boundary (inclusive) 64 * @param right double; the right boundary (not inclusive) 65 * @param top double; the top boundary (not inclusive) 66 */ 67 public Rectangle(final double left, final double bottom, final double right, final double top) 68 { 69 this.left = left; 70 this.bottom = bottom; 71 this.right = right; 72 this.top = top; 73 } 74 75 /** 76 * Retrieve the left boundary value. 77 * @return double; the left boundary value 78 */ 79 public double getLeft() 80 { 81 return this.left; 82 } 83 84 /** 85 * Retrieve the bottom boundary value. 86 * @return double; the bottom boundary value 87 */ 88 public double getBottom() 89 { 90 return this.bottom; 91 } 92 93 /** 94 * Retrieve the right boundary value. 95 * @return double; the right boundary value 96 */ 97 public double getRight() 98 { 99 return this.right; 100 } 101 102 /** 103 * Retrieve the top boundary value. 104 * @return double; the top boundary value 105 */ 106 public double getTop() 107 { 108 return this.top; 109 } 110 111 /** 112 * Return the width of this Rectangle. 113 * @return double; the width of this Rectangle 114 */ 115 public double getWidth() 116 { 117 return this.right - this.left; 118 } 119 120 /** 121 * Return the height of this Rectangle. 122 * @return double; the height of this Rectangle 123 */ 124 public double getHeight() 125 { 126 return this.top - this.bottom; 127 } 128 129 /** 130 * Determine if this Rectangle intersects another Rectangle. 131 * @param other Rectangle; the other rectangle 132 * @return boolean; true if the rectangles intersect, false if the rectangles do not intersect 133 */ 134 public boolean intersects(final Rectangle other) 135 { 136 return this.left < other.right && this.bottom < other.top && other.left < this.right && other.bottom < this.top; 137 } 138 139 /** 140 * Determine if this Rectangle contains a point. 141 * @param x double; x-coordinate of the point 142 * @param y double; y-coordinate of the point 143 * @return boolean; true if this Rectangle contains the point; false if this Rectangle does not contain the point 144 */ 145 public boolean contains(final double x, final double y) 146 { 147 return (this.left <= x && x < this.right && this.bottom <= y && y < this.top); 148 } 149 150 /** 151 * Determine if this Rectangle contains all points of another Rectangle. 152 * @param other Rectangle; the other rectangle 153 * @return boolean; true if this Rectangle contains all points of the other Rectangle; false if this Rectangle does not 154 * contain all points of the other Rectangle 155 */ 156 public boolean contains(final Rectangle other) 157 { 158 return other.left >= this.left && other.right <= this.right && other.bottom >= this.bottom && other.top <= this.top; 159 } 160 161 @Override 162 public String toString() 163 { 164 return "Rectangle [LB=" + this.left + "," + this.bottom + ", RT=" + this.right + "," + this.top + "]"; 165 } 166 167 }