diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-04-15 22:33:32 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-04-15 22:33:32 (GMT) |
commit | 1cb11b428ef1bee070af72676b7eb1fa325bb980 (patch) | |
tree | f098bff499691223ba9255a8e0500314cae20e6e /src/gui/math3d | |
parent | 10688c0168fc010671abc59f367c19357bb6776c (diff) | |
download | Qt-1cb11b428ef1bee070af72676b7eb1fa325bb980.zip Qt-1cb11b428ef1bee070af72676b7eb1fa325bb980.tar.gz Qt-1cb11b428ef1bee070af72676b7eb1fa325bb980.tar.bz2 |
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
Diffstat (limited to 'src/gui/math3d')
-rw-r--r-- | src/gui/math3d/qquaternion.cpp | 39 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.h | 2 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 1348fed..a91b0b9 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 ad6fddf..c05c641 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; |