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