Browse Source

Math: linear Quaternion interpolation.

pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
ed147ebe40
  1. 16
      src/Math/Quaternion.h
  2. 24
      src/Math/Test/MathQuaternionTest.cpp

16
src/Math/Quaternion.h

@ -33,6 +33,22 @@ namespace Magnum { namespace Math {
/** @brief %Quaternion */ /** @brief %Quaternion */
template<class T> class Quaternion { template<class T> class Quaternion {
public: public:
/**
* @brief Linear interpolation of two quaternions
* @param normalizedA First quaternion
* @param normalizedB Second quaternion
* @param t Interpolation phase (from range @f$ [0; 1] @f$)
*
* 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]
*/
inline static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.lengthSquared(), T(1)) && MathTypeTraits<T>::equals(normalizedB.lengthSquared(), T(1)),
"Math::Quaternion::lerp(): quaternions must be normalized", Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN()));
return ((T(1) - t)*normalizedA + t*normalizedB).normalized();
}
/** /**
* @brief Create quaternion from rotation * @brief Create quaternion from rotation
* @param angle Rotation angle (counterclockwise, in radians) * @param angle Rotation angle (counterclockwise, in radians)

24
src/Math/Test/MathQuaternionTest.cpp

@ -38,6 +38,7 @@ class QuaternionTest: public Corrade::TestSuite::Tester {
void invertedNormalized(); void invertedNormalized();
void rotation(); void rotation();
void matrix(); void matrix();
void lerp();
void debug(); void debug();
}; };
@ -58,6 +59,7 @@ QuaternionTest::QuaternionTest() {
&QuaternionTest::invertedNormalized, &QuaternionTest::invertedNormalized,
&QuaternionTest::rotation, &QuaternionTest::rotation,
&QuaternionTest::matrix, &QuaternionTest::matrix,
&QuaternionTest::lerp,
&QuaternionTest::debug); &QuaternionTest::debug);
} }
@ -166,6 +168,28 @@ void QuaternionTest::matrix() {
CORRADE_COMPARE((-q).matrix(), expected); CORRADE_COMPARE((-q).matrix(), expected);
} }
void QuaternionTest::lerp() {
Quaternion a = Quaternion::fromRotation(deg(15.0f), Vector3(1.0f/Constants<float>::sqrt3()));
Quaternion b = Quaternion::fromRotation(deg(23.0f), Vector3::xAxis());
std::ostringstream o;
Corrade::Utility::Error::setOutput(&o);
Quaternion notLerpA = Quaternion::lerp(a*3.0f, b, 0.35f);
CORRADE_COMPARE(notLerpA.vector(), Vector3());
CORRADE_COMPARE(notLerpA.scalar(), std::numeric_limits<float>::quiet_NaN());
CORRADE_COMPARE(o.str(), "Math::Quaternion::lerp(): quaternions must be normalized\n");
o.str("");
Quaternion notLerpB = Quaternion::lerp(a, b*-3.0f, 0.35f);
CORRADE_COMPARE(notLerpB.vector(), Vector3());
CORRADE_COMPARE(notLerpB.scalar(), std::numeric_limits<float>::quiet_NaN());
CORRADE_COMPARE(o.str(), "Math::Quaternion::lerp(): quaternions must be normalized\n");
Quaternion lerp = Quaternion::lerp(a, b, 0.35f);
CORRADE_COMPARE(lerp, Quaternion({0.119127f, 0.049134f, 0.049134f}, 0.990445f));
}
void QuaternionTest::debug() { void QuaternionTest::debug() {
std::ostringstream o; std::ostringstream o;

Loading…
Cancel
Save