summaryrefslogtreecommitdiffstats
path: root/tests/auto/gui/math3d
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2015-02-26 19:16:15 +0400
committerKonstantin Ritt <ritt.ks@gmail.com>2015-03-07 01:14:04 +0000
commit1e441d298db5e7ad1635067106e4b7ed251fd4bd (patch)
tree5fc797995ffbea1c1b904039399a1453a249d750 /tests/auto/gui/math3d
parentc4aea1ea20962bd12695147c8546558b02ad859c (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.cpp123
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.