summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2015-01-26 11:16:55 +0400
committerSean Harmer <sean.harmer@kdab.com>2015-01-28 12:37:50 +0000
commit14419b0a2b63c774e11dec10967495b19540bbb3 (patch)
tree4a87a3cf6e256b456378c20c5922f15500a9d0f9
parenta14559bc781b9ac7c61386bf563e62f6fde27d56 (diff)
Introduce QQuaternion::inverted()
Change-Id: I6de77082bb7c32e48fb7f7d765a58fdbe68db1fd Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/gui/math3d/qquaternion.cpp10
-rw-r--r--src/gui/math3d/qquaternion.h14
-rw-r--r--tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp29
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()
{