Browse Source

Math: added minmax() and Vector2::minmax().

No Vector<size, T> and std::initializer_list versions yet, as the
algorithm for it is pretty complicated and I'm not sure that they will
be used frequently enough to deserve their existence.
pull/34/head
Vladimír Vondruš 13 years ago
parent
commit
4059bd752f
  1. 26
      src/Math/Functions.h
  2. 14
      src/Math/Test/FunctionsTest.cpp
  3. 8
      src/Math/Test/Vector2Test.cpp
  4. 4
      src/Math/Vector.h
  5. 9
      src/Math/Vector2.h

26
src/Math/Functions.h

@ -25,8 +25,9 @@
*/
#include <cmath>
#include <type_traits>
#include <limits>
#include <type_traits>
#include <utility>
#include "Math/Vector.h"
@ -124,7 +125,7 @@ perform the operations component-wise.
/**
@brief Minimum
@see min(), clamp(), Vector::min()
@see @ref max(), @ref minmax(), @ref clamp(), @ref Vector::min()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T min(T a, T b);
@ -151,7 +152,7 @@ template<class T> inline T min(std::initializer_list<T> list) {
/**
@brief Maximum
@see max(), clamp(), Vector::max()
@see @ref min(), @ref minmax(), @ref clamp(), @ref Vector::max()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T max(const T& a, const T& b);
@ -175,6 +176,25 @@ template<class T> inline T max(std::initializer_list<T> list) {
return out;
}
/**
@brief Minimum and maximum of two values
@see @ref min(), @ref max(), @ref clamp(), @ref Vector2::minmax()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline std::pair<T, T> minmax(const T& a, const T& b);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, std::pair<T, T>>::type minmax(T a, T b) {
return a < b ? std::make_pair(a, b) : std::make_pair(b, a);
}
template<std::size_t size, class T> std::pair<Vector<size, T>, Vector<size, T>> minmax(const Vector<size, T>& a, const Vector<size, T>& b) {
std::pair<Vector<size, T>, Vector<size, T>> out{a, b};
for(std::size_t i = 0; i != size; ++i)
if(out.first[i] > out.second[i]) std::swap(out.first[i], out.second[i]);
return out;
}
#endif
/**
@brief Sign

14
src/Math/Test/FunctionsTest.cpp

@ -37,6 +37,7 @@ class FunctionsTest: public Corrade::TestSuite::Tester {
void minList();
void max();
void maxList();
void minmax();
void sign();
void abs();
@ -79,6 +80,7 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::minList,
&FunctionsTest::max,
&FunctionsTest::maxList,
&FunctionsTest::minmax,
&FunctionsTest::sign,
&FunctionsTest::abs,
@ -132,6 +134,18 @@ void FunctionsTest::maxList() {
Vector3i(9, -5, 18)}), Vector3i(9, 14, 18));
}
void FunctionsTest::minmax() {
const auto expectedScalar = std::make_pair(-5.0f, 4.0f);
CORRADE_COMPARE(Math::minmax(-5.0f, 4.0f), expectedScalar);
CORRADE_COMPARE(Math::minmax(4.0f, -5.0f), expectedScalar);
const Vector3 a(5.0f, -4.0f, 1.0f);
const Vector3 b(7.0f, -3.0f, 1.0f);
const std::pair<Vector3, Vector3> expectedVector{{5.0f, -4.0f, 1.0f}, {7.0f, -3.0f, 1.0f}};
CORRADE_COMPARE_AS(Math::minmax(a, b), expectedVector, std::pair<Vector3, Vector3>);
CORRADE_COMPARE_AS(Math::minmax(b, a), expectedVector, std::pair<Vector3, Vector3>);
}
void FunctionsTest::sign() {
CORRADE_COMPARE(Math::sign(3516), 1);
CORRADE_COMPARE(Math::sign(0.0f), 0.0f);

8
src/Math/Test/Vector2Test.cpp

@ -68,6 +68,7 @@ class Vector2Test: public Corrade::TestSuite::Tester {
void scales();
void perpendicular();
void aspectRatio();
void minmax();
void swizzleType();
void debug();
@ -93,6 +94,7 @@ Vector2Test::Vector2Test() {
&Vector2Test::scales,
&Vector2Test::perpendicular,
&Vector2Test::aspectRatio,
&Vector2Test::minmax,
&Vector2Test::swizzleType,
&Vector2Test::debug,
@ -202,6 +204,12 @@ void Vector2Test::aspectRatio() {
CORRADE_COMPARE(Vector2(3.0f, 4.0f).aspectRatio(), 0.75f);
}
void Vector2Test::minmax() {
const auto expected = std::make_pair(-5.0f, 4.0f);
CORRADE_COMPARE(Vector2(-5.0f, 4.0f).minmax(), expected);
CORRADE_COMPARE(Vector2(4.0f, -5.0f).minmax(), expected);
}
void Vector2Test::swizzleType() {
constexpr Vector<4, Int> orig;
constexpr auto a = swizzle<'y', 'a'>(orig);

4
src/Math/Vector.h

@ -514,14 +514,14 @@ template<std::size_t size, class T> class Vector {
/**
* @brief Minimal value in the vector
*
* @see Math::min()
* @see @ref Math::min(), @ref Vector2::minmax()
*/
T min() const;
/**
* @brief Maximal value in the vector
*
* @see Math::max()
* @see @ref Math::max(), @ref Vector2::minmax()
*/
T max() const;

9
src/Math/Vector2.h

@ -143,6 +143,15 @@ template<class T> class Vector2: public Vector<2, T> {
*/
T aspectRatio() const { return x()/y(); }
/**
* @brief Minimum and maximum value
*
* @see @ref min(), @ref max(), @ref Math::minmax()
*/
std::pair<T, T> minmax() const {
return x() < y() ? std::make_pair(x(), y()) : std::make_pair(y(), x());
}
MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(2, Vector2)
};

Loading…
Cancel
Save