Empty-rectangle results from java.awt.Rectangle.intersection: safe to rely on for containment checks?
0 reputation · 13 Oct 2025, 10:29 UTC
0 reputation · 13 Oct 2025, 10:29 UTC
I am working with java.awt.Rectangle and need to decide how to handle the result of intersection(Rectangle) when two rectangles do not overlap. The API documentation indicates the method returns an empty rectangle rather than null, and that a rectangle is empty when its width or height is less than or equal to zero.
My uncertainty is about downstream behavior: an empty rectangle contains no points, so a naive contains(x, y) check on the intersection result would simply return false. That seems convenient, but I am unsure whether relying on isEmpty() versus explicitly calling intersects() first is the intended pattern, especially since intersects avoids allocating a result object when only a boolean is needed.
A second concern is precision: Rectangle uses integer coordinates, while some of my inputs originate as floating-point geometry. I am unsure when the documented Rectangle2D.Double alternative becomes necessary, and whether negative width or height values in unnormalized inputs could silently produce empty results.
Is checking isEmpty() on the intersection result a documented, reliable way to detect non-overlap, or should intersects() always be preferred? At what point does integer precision justify switching to Rectangle2D? Do negative dimensions require normalization before any of these operations?
29775 reputation · 13 Oct 2025, 19:04 UTC
No. Checking isEmpty() on the result of Rectangle.intersection is a reliable way to detect non-overlap, but it is not a reliable way to detect containment. An empty intersection means no overlap. A non-empty intersection means overlap, but it does not prove that one rectangle is fully inside the other.
For containment decisions use Rectangle.contains(Rectangle) or Rectangle.contains(int x,int y). For a cheap boolean overlap test use Rectangle.intersects(Rectangle). Do not infer containment from intersection emptiness or non-emptiness.
Rectangle.intersection(Rectangle r) returns a new Rectangle whose bounds are the geometric overlap of the two rectangles. It does not modify either operand.Rectangle.isEmpty() is true when width <= 0 or height <= 0. That is the documented result for non-overlapping inputs, including edge-touching and zero-area cases.outer.contains(inner) is true only when the inner rectangle is fully inside the outer rectangle, edges inclusive.Rectangle.intersects(Rectangle) returns a boolean for overlap without allocating a result rectangle.Empty intersection is sufficient for detecting non-overlap, but a non-empty intersection only means partial or full overlap. Partial overlap yields a non-empty intersection without containment. Conversely, full containment also yields a non-empty intersection equal to the inner rectangle, so intersection non-emptiness cannot distinguish partial overlap from containment.
Integer coordinates in java.awt.Rectangle truncate floating-point geometry. When inputs originate as floating-point, Rectangle2D.Double preserves sub-pixel precision and avoids systematic truncation errors. Negative width or height in unnormalized inputs produces an empty rectangle by definition, which can silently look like non-overlap.
a.intersects(b) for a boolean, or a.intersection(b).isEmpty() if you also need the overlap bounds.outer.contains(inner). Do not rely on intersection.isEmpty() or on the size of the intersection.Rectangle2D.Double and its createIntersection, contains, and intersects methods to avoid integer truncation.One diagnostic detail that changes the recommendation: do you need strict interior containment or inclusive edge containment? Rectangle.contains is inclusive of edges. If you require strict interior, you must adjust the test, e.g., by shrinking the outer rectangle by 1 pixel or using Rectangle2D with epsilon checks.
Use comments to ask for clarification. Post a solution as an answer.
29,775 reputation · 13 Oct 2025, 19:50 UTC
The Rectangle.intersection method always returns a normalized rectangle: when the inputs overlap the result has non‑negative width and height positioned at the actual overlap; when they do not overlap it returns a zero‑width, zero‑height rectangle anchored at (0,0). Therefore testing isEmpty() (or width==0 && height==0) is a documented, reliable way to detect non‑overlap, but you must not use the empty rectangle’s x or y for further geometry because those values are implementation‑specific and not tied to the original inputs. If your source rectangles may have negative width or height (unnormalized), normalize them first—e.g., r = new Rectangle(Math.min(r.x, r.x+r.width), Math.min(r.y, r.y+r.height), Math.abs(r.width), Math.abs(r.height))—before calling intersection or intersects to avoid surprising empty results.