From 59852ace856b5951f6b7ae56feae005a51696fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 13 Aug 2018 19:19:56 +0200 Subject: [PATCH] Math: ability to slice Range into lower dimensions. --- doc/changelog.dox | 3 +++ src/Magnum/Math/Range.h | 30 ++++++++++++++++++++++++++++ src/Magnum/Math/Test/RangeTest.cpp | 32 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/doc/changelog.dox b/doc/changelog.dox index 54cff986e..df1273c28 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -66,6 +66,9 @@ See also: @ref Math::Color4::fromSrgb(UnsignedInt, T), @ref Math::Color3::toSrgbInt(), and @ref Math::Color4::toSrgbAlphaInt() for easier conversion of packed 24-/32-bit sRGB colors to and from @ref Math::Color3 / @ref Math::Color4 +- Added @ref Math::Range2D::x(), @ref Math::Range3D::x(), + @ref Math::Range2D::y(), @ref Math::Range3D::y(), @ref Math::Range3D::z() + and @ref Math::Range3D::y() for slicing ranges into lower dimensions - Added @ref Math::Constants::piQuarter() - Added a convenience function @ref Math::select() as a constant interpolation counterpart to @ref Math::lerp() diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index c8a3e7758..8d1c95148 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -317,6 +317,16 @@ template class Range2D: public Range<2, T> { T& top() { return Range<2, T>::max().y(); } constexpr T top() const { return Range<2, T>::max().y(); } /**< @overload */ + /** @brief Range in the X axis */ + constexpr Range<1, T> x() const { + return {Range<2, T>::min().x(), Range<2, T>::max().x()}; + } + + /** @brief Range in the Y axis */ + constexpr Range<1, T> y() const { + return {Range<2, T>::min().y(), Range<2, T>::max().y()}; + } + /** * @brief Range width * @@ -470,6 +480,26 @@ template class Range3D: public Range<3, T> { T& front() { return Range<3, T>::max().z(); } constexpr T front() const { return Range<3, T>::max().z(); } /**< @overload */ + /** @brief Range in the X axis */ + constexpr Range<1, T> x() const { + return {Range<3, T>::min().x(), Range<3, T>::max().x()}; + } + + /** @brief Range in the Y axis */ + constexpr Range<1, T> y() const { + return {Range<3, T>::min().y(), Range<3, T>::max().y()}; + } + + /** @brief Range in the Z axis */ + constexpr Range<1, T> z() const { + return {Range<3, T>::min().z(), Range<3, T>::max().z()}; + } + + /** @brief Range in the XY plane */ + constexpr Range<2, T> xy() const { + return {Range<3, T>::min().xy(), Range<3, T>::max().xy()}; + } + /** * @brief Range width * diff --git a/src/Magnum/Math/Test/RangeTest.cpp b/src/Magnum/Math/Test/RangeTest.cpp index 7ddc77f41..33d2c00f7 100644 --- a/src/Magnum/Math/Test/RangeTest.cpp +++ b/src/Magnum/Math/Test/RangeTest.cpp @@ -107,6 +107,7 @@ struct RangeTest: Corrade::TestSuite::Tester { void access(); void compare(); + void dimensionSlice(); void size(); void center(); @@ -144,6 +145,7 @@ RangeTest::RangeTest() { &RangeTest::access, &RangeTest::compare, + &RangeTest::dimensionSlice, &RangeTest::size, &RangeTest::center, @@ -409,6 +411,36 @@ void RangeTest::compare() { 1.0f + TypeTraits::epsilon()/2.0f)); } +void RangeTest::dimensionSlice() { + constexpr Range1Di lineX{34, 47}; + constexpr Range1Di lineY{23, 30}; + constexpr Range1Di lineZ{-17, 12}; + constexpr Range2Di rect{{34, 23}, {47, 30}}; + constexpr Range3Di cube{{34, 23, -17}, {47, 30, 12}}; + + constexpr Range1Di x2 = rect.x(); + constexpr Range1Di x3 = cube.x(); + CORRADE_COMPARE(x2, lineX); + CORRADE_COMPARE(x3, lineX); + CORRADE_COMPARE(rect.x(), lineX); + CORRADE_COMPARE(cube.x(), lineX); + + constexpr Range1Di y2 = rect.y(); + constexpr Range1Di y3 = cube.y(); + CORRADE_COMPARE(y2, lineY); + CORRADE_COMPARE(y3, lineY); + CORRADE_COMPARE(rect.y(), lineY); + CORRADE_COMPARE(cube.y(), lineY); + + constexpr Range1Di z = cube.z(); + CORRADE_COMPARE(z, lineZ); + CORRADE_COMPARE(cube.z(), lineZ); + + constexpr Range2Di xy = cube.xy(); + CORRADE_COMPARE(xy, rect); + CORRADE_COMPARE(cube.xy(), rect); +} + void RangeTest::size() { const Range1Di line(34, 47); const Range2Di rect({34, 23}, {47, 30});