summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/graphicsview/qgraphicstransform.cpp37
-rw-r--r--tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp22
2 files changed, 47 insertions, 12 deletions
diff --git a/src/gui/graphicsview/qgraphicstransform.cpp b/src/gui/graphicsview/qgraphicstransform.cpp
index 778cd94..ae88641 100644
--- a/src/gui/graphicsview/qgraphicstransform.cpp
+++ b/src/gui/graphicsview/qgraphicstransform.cpp
@@ -80,11 +80,7 @@
#include "qgraphicsitem_p.h"
#include "qgraphicstransform_p.h"
#include <QDebug>
-
-#include <math.h>
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE
@@ -355,7 +351,6 @@ public:
QGraphicsRotationPrivate()
: angle(0) {}
QPointF origin;
- qreal originY;
qreal angle;
};
@@ -475,13 +470,18 @@ void QGraphicsRotation::applyTo(QTransform *t) const
By default the axis is (0, 0, 1), giving QGraphicsRotation3D the same
default behavior as QGraphicsRotation (i.e., rotation around the Z axis).
+ Note: the final rotation is the combined effect of a rotation in
+ 3D space followed by a projection back to 2D. If several rotations
+ are performed in succession, they will not behave as expected unless
+ they were all around the Z axis.
+
\sa QGraphicsTransform, QGraphicsItem::setRotation(), QTransform::rotate()
*/
class QGraphicsRotation3DPrivate : public QGraphicsRotationPrivate
{
public:
- QGraphicsRotation3DPrivate() {}
+ QGraphicsRotation3DPrivate() : axis(0, 0, 1) {}
QVector3D axis;
};
@@ -526,6 +526,7 @@ void QGraphicsRotation3D::setAxis(const QVector3D &axis)
update();
}
+const qreal deg2rad = qreal(0.017453292519943295769); // pi/180
static const qreal inv_dist_to_plane = 1. / 1024.;
/*!
@@ -535,13 +536,27 @@ void QGraphicsRotation3D::applyTo(QTransform *t) const
{
Q_D(const QGraphicsRotation3D);
- if (d->angle == 0. ||
+ qreal a = d->angle;
+
+ if (a == 0. ||
(d->axis.z() == 0. && d->axis.y() == 0 && d->axis.x() == 0))
return;
- qreal rad = d->angle * 2. * M_PI / 360.;
- qreal c = ::cos(rad);
- qreal s = ::sin(rad);
+ qreal c, s;
+ if (a == 90. || a == -270.) {
+ s = 1.;
+ c = 0.;
+ } else if (a == 270. || a == -90.) {
+ s = -1.;
+ c = 0.;
+ } else if (a == 180.) {
+ s = 0.;
+ c = -1.;
+ } else {
+ qreal b = deg2rad*a;
+ s = qSin(b);
+ c = qCos(b);
+ }
qreal x = d->axis.x();
qreal y = d->axis.y();
diff --git a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp
index 672b1f1..c9481da 100644
--- a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp
+++ b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp
@@ -137,7 +137,10 @@ void tst_QGraphicsTransform::rotation()
void tst_QGraphicsTransform::rotation3d()
{
QGraphicsRotation3D rotation;
- rotation.setOrigin(QPointF(10, 10));
+ QCOMPARE(rotation.axis().x(), (qreal)0);
+ QCOMPARE(rotation.axis().y(), (qreal)0);
+ QCOMPARE(rotation.axis().z(), (qreal)1);
+ QCOMPARE(rotation.angle(), (qreal)0);
QTransform t;
rotation.applyTo(&t);
@@ -147,6 +150,23 @@ void tst_QGraphicsTransform::rotation3d()
rotation.setAngle(180);
+ QTransform t180;
+ t180.rotate(180.0f);
+
+ QCOMPARE(t, QTransform());
+ QVERIFY(qFuzzyCompare(rotation.transform(), t180));
+
+ rotation.setAxis(QVector3D(0, 0, 0));
+ rotation.setOrigin(QPointF(10, 10));
+
+ t = QTransform();
+ rotation.applyTo(&t);
+
+ QCOMPARE(t, QTransform());
+ QCOMPARE(rotation.transform(), QTransform());
+
+ rotation.setAngle(180);
+
QCOMPARE(t, QTransform());
QCOMPARE(rotation.transform(), QTransform());