From 4bef9ae7046d59349590822ad9d5cce66919e65c Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sun, 11 Jul 2021 21:23:16 -0400 Subject: [PATCH] Make Rect::contains() and intersects() inclusive and correctly handle infinite Rects. Add Rect::inf(). --- include/math.hpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/math.hpp b/include/math.hpp index 842fd7ad..b4011932 100644 --- a/include/math.hpp +++ b/include/math.hpp @@ -301,21 +301,28 @@ struct Rect { static Rect fromMinMax(Vec a, Vec b) { return Rect(a, b.minus(a)); } + static Rect inf() { + return Rect(Vec(-INFINITY, -INFINITY), Vec(INFINITY, INFINITY)); + } - /** Returns whether this Rect contains an entire point, inclusive on the top/left, non-inclusive on the bottom/right. */ + /** Returns whether this Rect contains an entire point, inclusive. */ bool contains(Vec v) const { - return pos.x <= v.x && v.x < pos.x + size.x - && pos.y <= v.y && v.y < pos.y + size.y; + // Handle the case where pos=-inf and size=inf + // i.e. don't ever use `pos + size` which is NAN + return (pos.x <= v.x) && (v.x - size.x <= pos.x) + && (pos.y <= v.y) && (v.y - size.y <= pos.y); } /** Returns whether this Rect contains an entire Rect. */ bool contains(Rect r) const { - return pos.x <= r.pos.x && r.pos.x + r.size.x <= pos.x + size.x - && pos.y <= r.pos.y && r.pos.y + r.size.y <= pos.y + size.y; + // Handle the case where pos=-inf and size=inf for either Rect + return (pos.x <= r.pos.x) && (r.pos.x - size.x <= pos.x - r.size.x) + && (pos.y <= r.pos.y) && (r.pos.y - size.y <= pos.y - r.size.y); } /** Returns whether this Rect overlaps with another Rect. */ bool intersects(Rect r) const { - return (pos.x + size.x > r.pos.x && r.pos.x + r.size.x > pos.x) - && (pos.y + size.y > r.pos.y && r.pos.y + r.size.y > pos.y); + // Handle the case where pos=-inf and size=inf for either Rect + return (r.pos.x - size.x <= pos.x) && (pos.x - r.size.x <= r.pos.x) + && (r.pos.y - size.y <= pos.y) && (pos.y - r.size.y <= r.pos.y); } bool equals(Rect r) const { return pos.equals(r.pos) && size.equals(r.size);