Browse Source

Math: document more non-obvious tricks.

pull/87/head
Vladimír Vondruš 12 years ago
parent
commit
64a02d68db
  1. 71
      src/Magnum/Math/Functions.h
  2. 41
      src/Magnum/Math/Test/FunctionsTest.cpp

71
src/Magnum/Math/Functions.h

@ -125,18 +125,19 @@ perform the operations component-wise.
/**
@brief Minimum
<em>NaN</em>s passed in @p value parameter are propagated.
@see @ref max(), @ref minmax(), @ref clamp(), @ref Vector::min()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T min(T a, T b);
template<class T> inline T min(T value, T min);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type min(T a, T b) {
return std::min(a, b);
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type min(T value, T min) {
return std::min(value, min);
}
template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size, T>& a, const Vector<size, T>& b) {
template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size, T>& value, const Vector<size, T>& min) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = std::min(a[i], b[i]);
out[i] = std::min(value[i], min[i]);
return out;
}
#endif
@ -152,18 +153,19 @@ template<class T> inline T min(std::initializer_list<T> list) {
/**
@brief Maximum
<em>NaN</em>s passed in @p value parameter are propagated.
@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);
template<class T> inline T max(T value, T max);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type max(T a, T b) {
return std::max(a, b);
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type max(T value, T max) {
return std::max(value, max);
}
template<std::size_t size, class T> Vector<size, T> max(const Vector<size, T>& a, const Vector<size, T>& b) {
template<std::size_t size, class T> Vector<size, T> max(const Vector<size, T>& value, const Vector<size, T>& max) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = std::max(a[i], b[i]);
out[i] = std::max(value[i], max[i]);
return out;
}
#endif
@ -195,6 +197,31 @@ template<std::size_t size, class T> std::pair<Vector<size, T>, Vector<size, T>>
}
#endif
/**
@brief Clamp value
Values smaller than @p min are set to @p min, values larger than @p max are
set to @p max. Equivalent to:
@code
Math::min(Math::max(value, min), max)
@endcode
<em>NaN</em>s passed in @p value parameter are propagated.
@see @ref min(), @ref max()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T, class U> inline T clamp(const T& value, U min, U max);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type clamp(T value, T min, T max) {
return std::min(std::max(value, min), max);
}
template<std::size_t size, class T> Vector<size, T> clamp(const Vector<size, T>& value, T min, T max) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = clamp(value[i], min, max);
return out;
}
#endif
/**
@brief Sign
@ -321,30 +348,6 @@ template<std::size_t size, class T> Vector<size, T> sqrtInverted(const Vector<si
}
#endif
/**
@brief Clamp value
Values smaller than @p min are set to @p min, values larger than @p max are
set to @p max. Equivalent to:
@code
Math::min(Math::max(value, min), max)
@endcode
@see @ref min(), @ref max()
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T, class U> inline T clamp(const T& value, U min, U max);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type clamp(T value, T min, T max) {
return std::min(std::max(value, min), max);
}
template<std::size_t size, class T> Vector<size, T> clamp(const Vector<size, T>& value, T min, T max) {
Vector<size, T> out;
for(std::size_t i = 0; i != size; ++i)
out[i] = clamp(value[i], min, max);
return out;
}
#endif
/**
@brief Linear interpolation of two values
@param a First value

41
src/Magnum/Math/Test/FunctionsTest.cpp

@ -39,6 +39,9 @@ class FunctionsTest: public Corrade::TestSuite::Tester {
void max();
void maxList();
void minmax();
void clamp();
void nanPropagation();
void sign();
void abs();
@ -48,7 +51,6 @@ class FunctionsTest: public Corrade::TestSuite::Tester {
void sqrt();
void sqrtInverted();
void clamp();
void lerp();
void lerpInverted();
void fma();
@ -71,6 +73,7 @@ class FunctionsTest: public Corrade::TestSuite::Tester {
typedef Math::Constants<Float> Constants;
typedef Math::Deg<Float> Deg;
typedef Math::Rad<Float> Rad;
typedef Math::Vector2<Float> Vector2;
typedef Math::Vector3<Float> Vector3;
typedef Math::Vector3<UnsignedByte> Vector3ub;
typedef Math::Vector3<Byte> Vector3b;
@ -82,6 +85,9 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::max,
&FunctionsTest::maxList,
&FunctionsTest::minmax,
&FunctionsTest::clamp,
&FunctionsTest::nanPropagation,
&FunctionsTest::sign,
&FunctionsTest::abs,
@ -91,7 +97,6 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::sqrt,
&FunctionsTest::sqrtInverted,
&FunctionsTest::clamp,
&FunctionsTest::lerp,
&FunctionsTest::lerpInverted,
&FunctionsTest::fma,
@ -147,6 +152,30 @@ void FunctionsTest::minmax() {
CORRADE_COMPARE_AS(Math::minmax(b, a), expectedVector, std::pair<Vector3, Vector3>);
}
void FunctionsTest::clamp() {
CORRADE_COMPARE(Math::clamp(0.5f, -1.0f, 5.0f), 0.5f);
CORRADE_COMPARE(Math::clamp(-1.6f, -1.0f, 5.0f), -1.0f);
CORRADE_COMPARE(Math::clamp(9.5f, -1.0f, 5.0f), 5.0f);
CORRADE_COMPARE(Math::clamp(Vector3(0.5f, -1.6f, 9.5f), -1.0f, 5.0f), Vector3(0.5f, -1.0f, 5.0f));
}
void FunctionsTest::nanPropagation() {
constexpr const Float NaN = std::numeric_limits<float>::quiet_NaN();
CORRADE_COMPARE(Math::min(NaN, 5.0f), NaN);
CORRADE_COMPARE(Math::min(Vector2{NaN, 6.0f}, Vector2{5.0f})[0], NaN);
CORRADE_COMPARE(Math::min(Vector2{NaN, 6.0f}, Vector2{5.0f})[1], 5.0f);
CORRADE_COMPARE(Math::max(NaN, 5.0f), NaN);
CORRADE_COMPARE(Math::max(Vector2{NaN, 4.0f}, Vector2{5.0f})[0], NaN);
CORRADE_COMPARE(Math::max(Vector2{NaN, 4.0f}, Vector2{5.0f})[1], 5.0f);
CORRADE_COMPARE(Math::clamp(NaN, 2.0f, 6.0f), NaN);
CORRADE_COMPARE(Math::clamp(Vector2{NaN, 1.0f}, 2.0f, 6.0f)[0], NaN);
CORRADE_COMPARE(Math::clamp(Vector2{NaN, 1.0f}, 2.0f, 6.0f)[1], 2.0f);
}
void FunctionsTest::sign() {
CORRADE_COMPARE(Math::sign(3516), 1);
CORRADE_COMPARE(Math::sign(0.0f), 0.0f);
@ -194,14 +223,6 @@ void FunctionsTest::sqrtInverted() {
CORRADE_COMPARE(Math::sqrtInverted(Vector3(1.0f, 4.0f, 16.0f)), Vector3(1.0f, 0.5f, 0.25f));
}
void FunctionsTest::clamp() {
CORRADE_COMPARE(Math::clamp(0.5f, -1.0f, 5.0f), 0.5f);
CORRADE_COMPARE(Math::clamp(-1.6f, -1.0f, 5.0f), -1.0f);
CORRADE_COMPARE(Math::clamp(9.5f, -1.0f, 5.0f), 5.0f);
CORRADE_COMPARE(Math::clamp(Vector3(0.5f, -1.6f, 9.5f), -1.0f, 5.0f), Vector3(0.5f, -1.0f, 5.0f));
}
void FunctionsTest::lerp() {
/* Floating-point / integral scalar */
CORRADE_COMPARE(Math::lerp(2.0f, 5.0f, 0.5f), 3.5f);

Loading…
Cancel
Save