From cc3631a243bd5f11e5668b7d3d055071fae5d80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 17 Jan 2024 17:18:57 +0100 Subject: [PATCH] Math: add a join() overload for joining a Range and a point. --- doc/changelog.dox | 2 ++ src/Magnum/Math/Range.h | 24 ++++++++++++++++++++++++ src/Magnum/Math/Test/RangeTest.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/doc/changelog.dox b/doc/changelog.dox index 653dd8009..5088f7e1c 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -665,6 +665,8 @@ See also: APIs that take sized views. - Added @ref Math::Range::scaled() and @ref Math::Range::scaledFromCenter() overloads taking a scalar +- Added a @ref Math::join(const Range&, const Vector&) + overload for joining a range and a point @subsubsection changelog-latest-changes-meshtools MeshTools library diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index 65e9ed4b3..342631f3d 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -780,6 +780,7 @@ template class Range3D: public Range<3, T> { Returns a range that contains both input ranges. If one of the ranges is empty, only the other is returned. Results are undefined if any range has a negative size. +@see @ref join(const Range&, const Vector&) */ template inline Range join(const Range& a, const Range& b) { if(a.min() == a.max()) return b; @@ -787,6 +788,29 @@ template inline Range join(const return {min(a.min(), b.min()), max(a.max(), b.max())}; } +/** @relatesalso Range +@brief Join a range and a point +@m_since_latest + +Returns a range that contains both the input range and the point. Compared to +@ref join(const Range&, const Range&) there's no +special casing for an empty range. Results are undefined if the range has a +negative size. +*/ +template inline Range join(const Range& a, + /* std::common_type has to be used so it's possible to pass Vector2 and + other subclasses, FFS */ + #ifdef DOXYGEN_GENERATING_OUTPUT + const Vector& b + #else + const typename std::common_type>::type& b + #endif +) { + /* Range::min() / max() return scalars for 1D, have to explicitly choose a + vector overload of Math::min() / max() to make it work with 1D vectors */ + return {min(a.min(), b), max(a.max(), b)}; +} + /** @relatesalso Range @brief Intersect two ranges diff --git a/src/Magnum/Math/Test/RangeTest.cpp b/src/Magnum/Math/Test/RangeTest.cpp index 5c71ca05d..08b966947 100644 --- a/src/Magnum/Math/Test/RangeTest.cpp +++ b/src/Magnum/Math/Test/RangeTest.cpp @@ -137,6 +137,8 @@ struct RangeTest: TestSuite::Tester { void intersectIntersects1D(); void join(); void join1D(); + void joinPoint(); + void joinPoint1D(); void strictWeakOrdering(); @@ -187,6 +189,8 @@ RangeTest::RangeTest() { &RangeTest::intersectIntersects1D, &RangeTest::join, &RangeTest::join1D, + &RangeTest::joinPoint, + &RangeTest::joinPoint1D, &RangeTest::strictWeakOrdering, @@ -917,6 +921,32 @@ void RangeTest::join1D() { CORRADE_COMPARE(Math::join(c, a), a); } +void RangeTest::joinPoint() { + Range2Di a{{12, 20}, {15, 35}}; + Range2Di empty{{12, 20}, {12, 20}}; + Vector2i b{13, 25}; + Vector2i c{10, 40}; + Vector2i d{20, 15}; + + CORRADE_COMPARE(Math::join(a, b), a); + CORRADE_COMPARE(Math::join(empty, b), (Range2Di{{12, 20}, {13, 25}})); + CORRADE_COMPARE(Math::join(a, c), (Range2Di{{10, 20}, {15, 40}})); + CORRADE_COMPARE(Math::join(a, d), (Range2Di{{12, 15}, {20, 35}})); +} + +void RangeTest::joinPoint1D() { + Range1Di a{12, 15}; + Range1Di empty{12, 12}; + Vector2i{13, 25}; + Vector2i{10, 40}; + Vector2i{20, 15}; + + CORRADE_COMPARE(Math::join(a, 13), a); + CORRADE_COMPARE(Math::join(empty, 13), (Range1Di{12, 13})); + CORRADE_COMPARE(Math::join(a, 10), (Range1Di{10, 15})); + CORRADE_COMPARE(Math::join(a, 20), (Range1Di{12, 20})); +} + void RangeTest::strictWeakOrdering() { StrictWeakOrdering o; const Range1D a{1.0f, 2.0f};