Browse Source

Math: moved lerp() from Vector to Functions.h.

It does nothing special for vectors (unlike e.g. quaternion LERP) and
scalar overload is useful too.
pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
0144c38a54
  1. 24
      src/Math/Functions.h
  2. 2
      src/Math/Quaternion.h
  3. 19
      src/Math/Test/FunctionsTest.cpp
  4. 14
      src/Math/Test/VectorTest.cpp
  5. 19
      src/Math/Vector.h

24
src/Math/Functions.h

@ -153,6 +153,30 @@ template<std::size_t size, class T> Vector<size, T> clamp(const Vector<size, T>&
}
#endif
/**
@brief Linear interpolation of two values
@param a First value
@param b Second value
@param t Interpolation phase (from range @f$ [0; 1] @f$)
The interpolation for vectors is done as in following, similarly for scalars: @f[
\boldsymbol v_{LERP} = (1 - t) \boldsymbol v_A + t \boldsymbol v_B
@f]
@see Quaternion::lerp()
@todo http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
(when SIMD is in place)
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T, class U> inline T lerp(const T& a, const T& b, U t);
#else
template<class T, class U> inline T lerp(T a, T b, U t) {
return (U(1) - t)*a + t*b;
}
template<std::size_t size, class T, class U> inline Vector<size, T> lerp(const Vector<size, T>& a, const Vector<size, T>& b, U t) {
return (U(1) - t)*a + t*b;
}
#endif
/**
@brief Normalize integral value

2
src/Math/Quaternion.h

@ -72,6 +72,7 @@ template<class T> class Quaternion {
* Expects that both quaternions are normalized. @f[
* q_{LERP} = \frac{(1 - t) q_A + t q_B}{|(1 - t) q_A + t q_B|}
* @f]
* @see slerp(), Math::lerp()
*/
inline static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)),
@ -91,6 +92,7 @@ template<class T> class Quaternion {
* ~~~~~~~~~~
* \theta = acos \left( \frac{q_A \cdot q_B}{|q_A| \cdot |q_B|} \right)
* @f]
* @see lerp()
*/
inline static Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)),

19
src/Math/Test/FunctionsTest.cpp

@ -28,6 +28,7 @@ class FunctionsTest: public Corrade::TestSuite::Tester {
void max();
void abs();
void clamp();
void lerp();
void normalizeUnsigned();
void normalizeSigned();
void denormalizeUnsigned();
@ -50,6 +51,7 @@ FunctionsTest::FunctionsTest() {
&FunctionsTest::max,
&FunctionsTest::abs,
&FunctionsTest::clamp,
&FunctionsTest::lerp,
&FunctionsTest::normalizeUnsigned,
&FunctionsTest::normalizeSigned,
&FunctionsTest::denormalizeUnsigned,
@ -85,6 +87,23 @@ void FunctionsTest::clamp() {
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);
CORRADE_COMPARE(Math::lerp(2, 5, 0.5f), 3);
/* Floating-point vector */
Vector3 a(-1.0f, 2.0f, 3.0f);
Vector3 b(3.0f, -2.0f, 11.0f);
CORRADE_COMPARE(Math::lerp(a, b, 0.25f), Vector3(0.0f, 1.0f, 5.0f));
/* Integer vector */
typedef Math::Vector<3, std::int32_t> Vector3ub;
Vector3ub c(0, 128, 64);
Vector3ub d(16, 0, 32);
CORRADE_COMPARE(Math::lerp(c, d, 0.25f), Vector3ub(4, 96, 56));
}
void FunctionsTest::normalizeUnsigned() {
CORRADE_COMPARE((Math::normalize<float, std::uint8_t>(0)), 0.0f);
CORRADE_COMPARE((Math::normalize<float, std::uint8_t>(255)), 1.0f);

14
src/Math/Test/VectorTest.cpp

@ -58,7 +58,6 @@ class VectorTest: public Corrade::TestSuite::Tester {
void projected();
void projectedOntoNormalized();
void angle();
void lerp();
void debug();
void configuration();
@ -101,7 +100,6 @@ VectorTest::VectorTest() {
&VectorTest::projected,
&VectorTest::projectedOntoNormalized,
&VectorTest::angle,
&VectorTest::lerp,
&VectorTest::debug,
&VectorTest::configuration);
@ -320,18 +318,6 @@ void VectorTest::angle() {
rad(1.162514f));
}
void VectorTest::lerp() {
Vector3 a(-1.0f, 2.0f, 3.0f);
Vector3 b(3.0f, -2.0f, 11.0f);
CORRADE_COMPARE(Vector3::lerp(a, b, 0.25f), Vector3(0.0f, 1.0f, 5.0f));
typedef Math::Vector<3, std::int32_t> Vector3ub;
Vector3ub c(0, 128, 64);
Vector3ub d(16, 0, 32);
CORRADE_COMPARE(Vector3ub::lerp(c, d, 0.25f), Vector3ub(4, 96, 56));
}
void VectorTest::debug() {
std::ostringstream o;
Debug(&o) << Vector4(0.5f, 15.0f, 1.0f, 1.0f);

19
src/Math/Vector.h

@ -90,22 +90,6 @@ template<std::size_t size, class T> class Vector {
return std::acos(dot(normalizedA, normalizedB));
}
/**
* @brief Linear interpolation of two vectors
* @param a First vector
* @param b Second vector
* @param t Interpolation phase (from range @f$ [0; 1] @f$)
*
* The interpolation is done as in following: @f[
* \boldsymbol v_{LERP} = (1 - t) \boldsymbol v_A + t \boldsymbol v_B
* @f]
* @todo http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
* (when SIMD is in place)
*/
template<class U> inline static Vector<size, T> lerp(const Vector<size, T>& a, const Vector<size, T>& b, U t) {
return (U(1) - t)*a + t*b;
}
/** @brief Construct zero-filled vector */
inline constexpr /*implicit*/ Vector(): _data() {}
@ -587,9 +571,6 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit
} \
inline constexpr static const Type<T>& from(const T* data) { \
return *reinterpret_cast<const Type<T>*>(data); \
} \
template<class U> inline static const Type<T> lerp(const Math::Vector<size, T>& a, const Math::Vector<size, T>& b, U t) { \
return Math::Vector<size, T>::lerp(a, b, t); \
} \
\
inline Type<T>& operator=(const Type<T>& other) { \

Loading…
Cancel
Save