Introduce QQuaternion::inverted()

Change-Id: I6de77082bb7c32e48fb7f7d765a58fdbe68db1fd
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
bb10
Konstantin Ritt 2015-01-26 11:16:55 +04:00 committed by Sean Harmer
parent a14559bc78
commit 14419b0a2b
3 changed files with 53 additions and 0 deletions

View File

@ -273,6 +273,16 @@ void QQuaternion::normalize()
wp /= len;
}
/*!
\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

View File

@ -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);

View File

@ -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()
{