Browse Source

Math: ability to construct a Range from std::pair.

Useful to feed the output from Math::minmax() directly to a Range.
pull/272/head
Vladimír Vondruš 8 years ago
parent
commit
64f8a90095
  1. 2
      doc/changelog.dox
  2. 9
      doc/snippets/MagnumMath.cpp
  3. 4
      src/Magnum/Math/Functions.h
  4. 21
      src/Magnum/Math/Range.h
  5. 20
      src/Magnum/Math/Test/RangeTest.cpp

2
doc/changelog.dox

@ -73,6 +73,8 @@ See also:
to @ref Math::join() for operating with @ref Math::Range instances to @ref Math::join() for operating with @ref Math::Range instances
- Added @ref Math::Range::contains() overloading taking a range, in addition - Added @ref Math::Range::contains() overloading taking a range, in addition
to vector to vector
- @ref Math::Range is now constructible from a @ref std::pair of values,
making it usable in combination with @ref Math::minmax(), for example
- Added @ref Math::Constants::piQuarter() - Added @ref Math::Constants::piQuarter()
- Added a convenience function @ref Math::select() as a constant - Added a convenience function @ref Math::select() as a constant
interpolation counterpart to @ref Math::lerp() interpolation counterpart to @ref Math::lerp()

9
doc/snippets/MagnumMath.cpp

@ -28,6 +28,7 @@
#include "Magnum/Math/DualComplex.h" #include "Magnum/Math/DualComplex.h"
#include "Magnum/Math/DualQuaternion.h" #include "Magnum/Math/DualQuaternion.h"
#include "Magnum/Math/Half.h" #include "Magnum/Math/Half.h"
#include "Magnum/Math/Range.h"
#include "Magnum/Math/Algorithms/GramSchmidt.h" #include "Magnum/Math/Algorithms/GramSchmidt.h"
using namespace Magnum; using namespace Magnum;
@ -858,4 +859,12 @@ Debug{} << Math::Vector3<UnsignedShort>{a}; // prints {16968, 48552, 15993}
/* [Half-usage-vector] */ /* [Half-usage-vector] */
} }
{
/* [Range-construct-minmax] */
Vector3 a, b, c;
Range3D bounds{Math::minmax({a, b, c})};
/* [Range-construct-minmax] */
static_cast<void>(bounds);
}
} }

4
src/Magnum/Math/Functions.h

@ -345,7 +345,8 @@ template<class T> inline T max(std::initializer_list<T> list) {
/** /**
@brief Minimum and maximum of two values @brief Minimum and maximum of two values
@see @ref min(), @ref max(), @ref clamp(), @ref Vector::minmax() @see @ref min(), @ref max(), @ref clamp(), @ref Vector::minmax(),
@ref Range::Range(const std::pair<VectorType, VectorType>&)
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline std::pair<T, T> minmax(const T& a, const T& b); template<class T> inline std::pair<T, T> minmax(const T& a, const T& b);
@ -379,6 +380,7 @@ namespace Implementation {
@brief Minimum and maximum of a range @brief Minimum and maximum of a range
If the range is empty, returns default-constructed values. If the range is empty, returns default-constructed values.
@see @ref Range::Range(const std::pair<VectorType, VectorType>&)
*/ */
template<class T> std::pair<T, T> minmax(Corrade::Containers::ArrayView<const T> range) { template<class T> std::pair<T, T> minmax(Corrade::Containers::ArrayView<const T> range) {
if(range.empty()) return {}; if(range.empty()) return {};

21
src/Magnum/Math/Range.h

@ -82,9 +82,28 @@ template<UnsignedInt dimensions, class T> class Range {
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit Range(NoInitT) noexcept: _min{NoInit}, _max{NoInit} {} explicit Range(NoInitT) noexcept: _min{NoInit}, _max{NoInit} {}
/** @brief Construct range from minimal and maximal coordinates */ /** @brief Construct a range from minimal and maximal coordinates */
constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max) noexcept: _min{min}, _max{max} {} constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max) noexcept: _min{min}, _max{max} {}
/**
* @brief Construct a range from a pair of minimal and maximal coordinates
*
* Useful in combination with e.g. @ref minmax(), here for example to
* calculate bounds of a triangle:
*
* @snippet MagnumMath.cpp Range-construct-minmax
*
* @todo std::pair constructors are not constexpr in C++11, make it so in C++14 */
/*implicit*/ Range(const std::pair<VectorType, VectorType>& minmax) noexcept:
_min{minmax.first}, _max{minmax.second} {}
/** @overload */
/** @todo std::pair constructors are not constexpr in C++11, make it so in C++14 */
#ifndef DOXYGEN_GENERATING_OUTPUT
template<UnsignedInt d = dimensions, class = std::enable_if<d != 1>>
#endif
/*implicit*/ Range(const std::pair<Vector<dimensions, T>, Vector<dimensions, T>>& minmax) noexcept: _min{minmax.first}, _max{minmax.second} {}
/** /**
* @brief Construct range from another of different type * @brief Construct range from another of different type
* *

20
src/Magnum/Math/Test/RangeTest.cpp

@ -101,6 +101,7 @@ struct RangeTest: Corrade::TestSuite::Tester {
void constructDefault(); void constructDefault();
void constructNoInit(); void constructNoInit();
void constructFromSize(); void constructFromSize();
void constructPair();
void constructConversion(); void constructConversion();
void constructCopy(); void constructCopy();
void convert(); void convert();
@ -141,6 +142,7 @@ RangeTest::RangeTest() {
&RangeTest::constructDefault, &RangeTest::constructDefault,
&RangeTest::constructNoInit, &RangeTest::constructNoInit,
&RangeTest::constructFromSize, &RangeTest::constructFromSize,
&RangeTest::constructPair,
&RangeTest::constructConversion, &RangeTest::constructConversion,
&RangeTest::constructCopy, &RangeTest::constructCopy,
&RangeTest::convert, &RangeTest::convert,
@ -238,6 +240,24 @@ void RangeTest::constructFromSize() {
CORRADE_COMPARE(Range3Di::fromSize({3, 5, -7}, {23, 78, 9}), Range3Di({3, 5, -7}, {26, 83, 2})); CORRADE_COMPARE(Range3Di::fromSize({3, 5, -7}, {23, 78, 9}), Range3Di({3, 5, -7}, {26, 83, 2}));
} }
void RangeTest::constructPair() {
Vector2i a{10, 22};
Vector2i b{30, 18};
Vector2i c{20, 25};
Range1Di bounds1a{Math::minmax<Math::Vector<1, Int>>({a.x(), b.x(), c.x()})};
Range1Di bounds1b{std::pair<Math::Vector<1, Int>, Math::Vector<1, Int>>{10, 30}};
Range1Di bounds1c{10, 30};
CORRADE_COMPARE(bounds1a, bounds1c);
CORRADE_COMPARE(bounds1b, bounds1c);
Range2Di bounds2a{Math::minmax({a, b, c})};
Range2Di bounds2b{std::pair<Math::Vector<2, Int>, Math::Vector<2, Int>>{{10, 18}, {30, 25}}};
Range2Di bounds2c{{10, 18}, {30, 25}};
CORRADE_COMPARE(bounds2a, bounds2c);
CORRADE_COMPARE(bounds2b, bounds2c);
}
void RangeTest::constructConversion() { void RangeTest::constructConversion() {
constexpr Range1D a(1.3f, -15.0f); constexpr Range1D a(1.3f, -15.0f);
constexpr Range2D b({1.3f, 2.7f}, {-15.0f, 7.0f}); constexpr Range2D b({1.3f, 2.7f}, {-15.0f, 7.0f});

Loading…
Cancel
Save