diff options
-rw-r--r-- | src/gui/math3d/qquaternion.cpp | 10 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.h | 14 | ||||
-rw-r--r-- | tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp | 29 |
3 files changed, 53 insertions, 0 deletions
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index f1af8922ca..23409189ac 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -274,6 +274,16 @@ void QQuaternion::normalize() } /*! + \fn QQuaternion QQuaternion::inverted() const + \since 5.5 + + Returns the inverse of this quaternion. + If this quaternion is null, then a null quaternion is returned. + + \sa isNull(), length() +*/ + +/*! \fn QQuaternion QQuaternion::conjugate() const Returns the conjugate of this quaternion, which is diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index e0e52cefdd..2bef926b76 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -82,6 +82,8 @@ public: QQuaternion normalized() const; void normalize(); + inline QQuaternion inverted() const; + QQuaternion conjugate() const; QVector3D rotatedVector(const QVector3D& vector) const; @@ -152,6 +154,18 @@ inline void QQuaternion::setY(float aY) { yp = aY; } inline void QQuaternion::setZ(float aZ) { zp = aZ; } inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; } +inline QQuaternion QQuaternion::inverted() const +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp) + + double(zp) * double(zp) + + double(wp) * double(wp); + if (!qFuzzyIsNull(len)) + return QQuaternion(wp / len, -xp / len, -yp / len, -zp / len); + return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); +} + inline QQuaternion QQuaternion::conjugate() const { return QQuaternion(wp, -xp, -yp, -zp); diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index cdbc242640..ecf8fbfefe 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -54,6 +54,9 @@ private slots: void normalize_data(); void normalize(); + void inverted_data(); + void inverted(); + void compare(); void add_data(); @@ -291,6 +294,32 @@ void tst_QQuaternion::normalize() QCOMPARE(v.length(), 1.0f); } +void tst_QQuaternion::inverted_data() +{ + // Use the same test data as the length test. + length_data(); +} +void tst_QQuaternion::inverted() +{ + QFETCH(float, x); + QFETCH(float, y); + QFETCH(float, z); + QFETCH(float, w); + QFETCH(float, len); + + QQuaternion v(w, x, y, z); + QQuaternion u = v.inverted(); + if (v.isNull()) { + QVERIFY(u.isNull()); + } else { + len *= len; + QCOMPARE(-u.x() * len, v.x()); + QCOMPARE(-u.y() * len, v.y()); + QCOMPARE(-u.z() * len, v.z()); + QCOMPARE(u.scalar() * len, v.scalar()); + } +} + // Test the comparison operators for quaternions. void tst_QQuaternion::compare() { |