From 5d784deb71edd1e6584cd2f118d27dd3be2da5e6 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 9 Feb 2015 17:50:25 +0400 Subject: [QQuaternion] Introduce toAxisAndAngle() This operation is the exact opposite to QQuaternion::fromAxisAndAngle() (so that it is a way to extract the axis and angle values suitable to create the same quaternion via QQuaternion::fromAxisAndAngle()). Change-Id: I41fda58f5fb2b867cccd6b2faf58ab671fa070da Reviewed-by: Laszlo Agocs --- src/gui/math3d/qquaternion.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/gui/math3d/qquaternion.cpp') diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 8e59e8a2f1..9c8fa3310d 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -362,9 +362,22 @@ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const #ifndef QT_NO_VECTOR3D +/*! + \fn void QQuaternion::toAxisAndAngle(QVector3D *axis, float *angle) const + \since 5.5 + \overload + + Extracts a 3D axis \a axis and a rotating angle \a angle (in degrees) + that corresponds to this quaternion. + + \sa fromAxisAndAngle() +*/ + /*! Creates a normalized quaternion that corresponds to rotating through \a angle degrees about the specified 3D \a axis. + + \sa toAxisAndAngle() */ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle) { @@ -381,9 +394,46 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, float angle) #endif +/*! + \since 5.5 + + Extracts a 3D axis (\a x, \a y, \a z) and a rotating angle \a angle (in degrees) + that corresponds to this quaternion. + + \sa fromAxisAndAngle() +*/ +void QQuaternion::toAxisAndAngle(float *x, float *y, float *z, float *angle) const +{ + Q_ASSERT(x && y && z && angle); + + // The quaternion representing the rotation is + // q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k) + + float length = xp * xp + yp * yp + zp * zp; + if (!qFuzzyIsNull(length)) { + *x = xp; + *y = yp; + *z = zp; + if (!qFuzzyIsNull(length - 1.0f)) { + length = sqrtf(length); + *x /= length; + *y /= length; + *z /= length; + } + *angle = 2.0f * acosf(wp); + } else { + // angle is 0 (mod 2*pi), so any axis will fit + *x = *y = *z = *angle = 0.0f; + } + + *angle = qRadiansToDegrees(*angle); +} + /*! Creates a normalized quaternion that corresponds to rotating through \a angle degrees about the 3D axis (\a x, \a y, \a z). + + \sa toAxisAndAngle() */ QQuaternion QQuaternion::fromAxisAndAngle (float x, float y, float z, float angle) -- cgit v1.2.3