diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2015-02-26 19:16:15 +0400 |
---|---|---|
committer | Konstantin Ritt <ritt.ks@gmail.com> | 2015-03-07 01:14:04 +0000 |
commit | 1e441d298db5e7ad1635067106e4b7ed251fd4bd (patch) | |
tree | 5fc797995ffbea1c1b904039399a1453a249d750 /tests/auto/gui/math3d | |
parent | c4aea1ea20962bd12695147c8546558b02ad859c (diff) |
[QQuaternion] Add a way to convert to/from orthonormal axes
It is just a convenience wrapper
around convertion to/from the rotation matrix.
Change-Id: I27511b43866827172960b0152f1c7b65da857f6f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'tests/auto/gui/math3d')
-rw-r--r-- | tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp | 123 |
1 files changed, 95 insertions, 28 deletions
diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index e358937a62..6b8eeeaca5 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -35,6 +35,52 @@ #include <QtCore/qmath.h> #include <QtGui/qquaternion.h> +// This is a more tolerant version of qFuzzyCompare that also handles the case +// where one or more of the values being compare are close to zero +static inline bool myFuzzyCompare(float p1, float p2) +{ + if (qFuzzyIsNull(p1) && qFuzzyIsNull(p2)) + return true; + return qAbs(qAbs(p1) - qAbs(p2)) <= 0.00003f; +} + +static inline bool myFuzzyCompare(const QVector3D &v1, const QVector3D &v2) +{ + return myFuzzyCompare(v1.x(), v2.x()) + && myFuzzyCompare(v1.y(), v2.y()) + && myFuzzyCompare(v1.z(), v2.z()); +} + +static inline bool myFuzzyCompare(const QQuaternion &q1, const QQuaternion &q2) +{ + const float d = QQuaternion::dotProduct(q1, q2); + return myFuzzyCompare(d * d, 1.0f); +} + +static inline bool myFuzzyCompareRadians(float p1, float p2) +{ + static const float fPI = float(M_PI); + if (p1 < -fPI) + p1 += 2.0f * fPI; + else if (p1 > fPI) + p1 -= 2.0f * fPI; + + if (p2 < -fPI) + p2 += 2.0f * fPI; + else if (p2 > fPI) + p2 -= 2.0f * fPI; + + return qAbs(qAbs(p1) - qAbs(p2)) <= qDegreesToRadians(0.05f); +} + +static inline bool myFuzzyCompareDegrees(float p1, float p2) +{ + p1 = qDegreesToRadians(p1); + p2 = qDegreesToRadians(p2); + return myFuzzyCompareRadians(p1, p2); +} + + class tst_QQuaternion : public QObject { Q_OBJECT @@ -89,6 +135,9 @@ private slots: void fromRotationMatrix_data(); void fromRotationMatrix(); + void fromAxes_data(); + void fromAxes(); + void fromEulerAngles_data(); void fromEulerAngles(); @@ -826,40 +875,58 @@ void tst_QQuaternion::fromRotationMatrix() QVERIFY(qFuzzyCompare(answer, result) || qFuzzyCompare(-answer, result)); } -// This is a more tolerant version of qFuzzyCompare that also handles the case -// where one or more of the values being compare are close to zero -static inline bool myFuzzyCompare(float p1, float p2) +// Test quaternion convertion to and from orthonormal axes. +void tst_QQuaternion::fromAxes_data() { - if (qFuzzyIsNull(p1)) - return qFuzzyIsNull(p2); - if (qFuzzyIsNull(p2)) - return false; - // a very slightly looser version of qFuzzyCompare - // for use with values that are not very close to zero - return qAbs(p1 - p2) <= 0.00003f * qMin(qAbs(p1), qAbs(p2)); -} + QTest::addColumn<float>("x1"); + QTest::addColumn<float>("y1"); + QTest::addColumn<float>("z1"); + QTest::addColumn<float>("angle"); + QTest::addColumn<QVector3D>("xAxis"); + QTest::addColumn<QVector3D>("yAxis"); + QTest::addColumn<QVector3D>("zAxis"); -static inline bool myFuzzyCompareRadians(float p1, float p2) -{ - static const float fPI = float(M_PI); - if (p1 < -fPI) - p1 += 2.0f * fPI; - else if (p1 > fPI) - p1 -= 2.0f * fPI; + QTest::newRow("null") + << 0.0f << 0.0f << 0.0f << 0.0f + << QVector3D(1, 0, 0) << QVector3D(0, 1, 0) << QVector3D(0, 0, 1); - if (p2 < -fPI) - p2 += 2.0f * fPI; - else if (p2 > fPI) - p2 -= 2.0f * fPI; + QTest::newRow("xonly") + << 1.0f << 0.0f << 0.0f << 90.0f + << QVector3D(1, 0, 0) << QVector3D(0, 0, 1) << QVector3D(0, -1, 0); - return qAbs(qAbs(p1) - qAbs(p2)) <= qDegreesToRadians(0.05f); -} + QTest::newRow("yonly") + << 0.0f << 1.0f << 0.0f << 180.0f + << QVector3D(-1, 0, 0) << QVector3D(0, 1, 0) << QVector3D(0, 0, -1); -static inline bool myFuzzyCompareDegrees(float p1, float p2) + QTest::newRow("zonly") + << 0.0f << 0.0f << 1.0f << 270.0f + << QVector3D(0, -1, 0) << QVector3D(1, 0, 0) << QVector3D(0, 0, 1); + + QTest::newRow("complex") + << 1.0f << 2.0f << -3.0f << 45.0f + << QVector3D(0.728028, -0.525105, -0.440727) << QVector3D(0.608789, 0.790791, 0.0634566) << QVector3D(0.315202, -0.314508, 0.895395); +} +void tst_QQuaternion::fromAxes() { - p1 = qDegreesToRadians(p1); - p2 = qDegreesToRadians(p2); - return myFuzzyCompareRadians(p1, p2); + QFETCH(float, x1); + QFETCH(float, y1); + QFETCH(float, z1); + QFETCH(float, angle); + QFETCH(QVector3D, xAxis); + QFETCH(QVector3D, yAxis); + QFETCH(QVector3D, zAxis); + + QQuaternion result = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle); + + QVector3D axes[3]; + result.getAxes(&axes[0], &axes[1], &axes[2]); + QVERIFY(myFuzzyCompare(axes[0], xAxis)); + QVERIFY(myFuzzyCompare(axes[1], yAxis)); + QVERIFY(myFuzzyCompare(axes[2], zAxis)); + + QQuaternion answer = QQuaternion::fromAxes(axes[0], axes[1], axes[2]); + + QVERIFY(qFuzzyCompare(answer, result) || qFuzzyCompare(-answer, result)); } // Test quaternion creation from an axis and an angle. |