From 1cb11b428ef1bee070af72676b7eb1fa325bb980 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 16 Apr 2009 08:33:32 +1000 Subject: Add the QQuaternion::nlerp() function as a counterpart to slerp() nlerp() implements "normalized linear interpolation", which is faster than slerp() and gives approximate results that are good enough for some applications. Reviewed-by: trustme --- src/gui/math3d/qquaternion.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/gui/math3d/qquaternion.h | 2 ++ 2 files changed, 41 insertions(+) (limited to 'src/gui/math3d') diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 1348fed322..a91b0b9d4f 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -484,6 +484,8 @@ QQuaternion QQuaternion::fromAxisAndAngle If \a t is less than or equal to 0, then \a q1 will be returned. If \a t is greater than or equal to 1, then \a q2 will be returned. + + \sa nlerp() */ QQuaternion QQuaternion::slerp (const QQuaternion& q1, const QQuaternion& q2, qreal t) @@ -522,6 +524,43 @@ QQuaternion QQuaternion::slerp return q1 * factor1 + q2b * factor2; } +/*! + Interpolates along the shortest linear path between the rotational + positions \a q1 and \a q2. The value \a t should be between 0 and 1, + indicating the distance to travel between \a q1 and \a q2. + The result will be normalized(). + + If \a t is less than or equal to 0, then \a q1 will be returned. + If \a t is greater than or equal to 1, then \a q2 will be returned. + + The nlerp() function is typically faster than slerp() and will + give approximate results to spherical interpolation that are + good enough for some applications. + + \sa slerp() +*/ +QQuaternion QQuaternion::nlerp + (const QQuaternion& q1, const QQuaternion& q2, qreal t) +{ + // Handle the easy cases first. + if (t <= 0.0f) + return q1; + else if (t >= 1.0f) + return q2; + + // Determine the angle between the two quaternions. + QQuaternion q2b; + qreal dot; + dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; + if (dot >= 0.0f) + q2b = q2; + else + q2b = -q2; + + // Perform the linear interpolation. + return (q1 * (1.0f - t) + q2b * t).normalized(); +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QQuaternion &q) diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index ad6fddfb73..c05c6413b9 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -126,6 +126,8 @@ public: static QQuaternion slerp (const QQuaternion& q1, const QQuaternion& q2, qreal t); + static QQuaternion nlerp + (const QQuaternion& q1, const QQuaternion& q2, qreal t); private: float wp, xp, yp, zp; -- cgit v1.2.3