diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/math3d/qmatrix4x4.cpp | 39 | ||||
-rw-r--r-- | src/gui/math3d/qmatrix4x4.h | 6 | ||||
-rw-r--r-- | src/gui/painting/qtransform.cpp | 86 | ||||
-rw-r--r-- | src/gui/painting/qtransform.h | 9 |
4 files changed, 113 insertions, 27 deletions
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 0e5db480d7..39625cdfb4 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1164,12 +1164,15 @@ void QMatrix4x4::rotate(float angle, float x, float y, float z) /*! \internal */ -void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) +void QMatrix4x4::projectedRotate(float angle, float x, float y, float z, float distanceToPlane) { // Used by QGraphicsRotation::applyTo() to perform a rotation // and projection back to 2D in a single step. + if (qIsNull(distanceToPlane)) + return rotate(angle, x, y, z); if (angle == 0.0f) return; + float c, s; if (angle == 90.0f || angle == -270.0f) { s = 1.0f; @@ -1185,6 +1188,8 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) c = std::cos(a); s = std::sin(a); } + + const qreal d = 1.0 / distanceToPlane; if (x == 0.0f) { if (y == 0.0f) { if (z != 0.0f) { @@ -1208,10 +1213,11 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) // Rotate around the Y axis. if (y < 0) s = -s; - m[0][0] = m[0][0] * c + m[3][0] * s * inv_dist_to_plane; - m[0][1] = m[0][1] * c + m[3][1] * s * inv_dist_to_plane; - m[0][2] = m[0][2] * c + m[3][2] * s * inv_dist_to_plane; - m[0][3] = m[0][3] * c + m[3][3] * s * inv_dist_to_plane; + s *= d; + m[0][0] = m[0][0] * c + m[3][0] * s; + m[0][1] = m[0][1] * c + m[3][1] * s; + m[0][2] = m[0][2] * c + m[3][2] * s; + m[0][3] = m[0][3] * c + m[3][3] * s; flagBits = General; return; } @@ -1219,10 +1225,11 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) // Rotate around the X axis. if (x < 0) s = -s; - m[1][0] = m[1][0] * c - m[3][0] * s * inv_dist_to_plane; - m[1][1] = m[1][1] * c - m[3][1] * s * inv_dist_to_plane; - m[1][2] = m[1][2] * c - m[3][2] * s * inv_dist_to_plane; - m[1][3] = m[1][3] * c - m[3][3] * s * inv_dist_to_plane; + s *= d; + m[1][0] = m[1][0] * c - m[3][0] * s; + m[1][1] = m[1][1] * c - m[3][1] * s; + m[1][2] = m[1][2] * c - m[3][2] * s; + m[1][3] = m[1][3] * c - m[3][3] * s; flagBits = General; return; } @@ -1249,14 +1256,24 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) rot.m[1][2] = 0.0f; rot.m[2][2] = 1.0f; rot.m[3][2] = 0.0f; - rot.m[0][3] = (x * z * ic - y * s) * -inv_dist_to_plane; - rot.m[1][3] = (y * z * ic + x * s) * -inv_dist_to_plane; + rot.m[0][3] = (x * z * ic - y * s) * -d; + rot.m[1][3] = (y * z * ic + x * s) * -d; rot.m[2][3] = 0.0f; rot.m[3][3] = 1.0f; rot.flagBits = General; *this *= rot; } +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +/*! + \internal +*/ +void QMatrix4x4::projectedRotate(float angle, float x, float y, float z) +{ + projectedRotate(angle, x, y, z, 1024.0); +} +#endif + /*! \fn int QMatrix4x4::flags() const \internal diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 0af8738b61..f8e5bc4314 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -154,7 +154,13 @@ public: friend Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m); #endif +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + void projectedRotate(float angle, float x, float y, float z, float distanceToPlane); + // ### Qt7: Remove void projectedRotate(float angle, float x, float y, float z); +#else + void projectedRotate(float angle, float x, float y, float z, float distanceToPlane = 1024.0); +#endif // When matrices are multiplied, the flag bits are or-ed together. // Note that the ordering of the bit values matters. (ident < t < s < r2d < r < p) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 5fa5d04e54..ea5fe8030f 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -533,28 +533,33 @@ QTransform & QTransform::shear(qreal sh, qreal sv) return *this; } -const qreal inv_dist_to_plane = 1. / 1024.; - /*! - \fn QTransform &QTransform::rotate(qreal angle, Qt::Axis axis) + \since 6.5 - Rotates the coordinate system counterclockwise by the given \a angle - about the specified \a axis and returns a reference to the matrix. + Rotates the coordinate system counterclockwise by the given angle \a a + about the specified \a axis at distance \a distanceToPlane from the + screen and returns a reference to the matrix. +//! [transform-rotate-note] Note that if you apply a QTransform to a point defined in widget coordinates, the direction of the rotation will be clockwise because the y-axis points downwards. The angle is specified in degrees. +//! [transform-rotate-note] + + If \a distanceToPlane is zero, it will be ignored. This is suitable + for implementing orthographic projections where the z coordinate should + be dropped rather than projected. \sa setMatrix() */ -QTransform & QTransform::rotate(qreal a, Qt::Axis axis) +QTransform & QTransform::rotate(qreal a, Qt::Axis axis, qreal distanceToPlane) { if (a == 0) return *this; #ifndef QT_NO_DEBUG - if (qIsNaN(a)) { + if (qIsNaN(a) || qIsNaN(distanceToPlane)) { nanWarning("rotate"); return *this; } @@ -617,13 +622,16 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis) if (m_dirty < TxRotate) m_dirty = TxRotate; } else { + if (!qIsNull(distanceToPlane)) + sina /= distanceToPlane; + QTransform result; if (axis == Qt::YAxis) { result.m_matrix[0][0] = cosa; - result.m_matrix[0][2] = -sina * inv_dist_to_plane; + result.m_matrix[0][2] = -sina; } else { result.m_matrix[1][1] = cosa; - result.m_matrix[1][2] = -sina * inv_dist_to_plane; + result.m_matrix[1][2] = -sina; } result.m_type = TxProject; *this = result * *this; @@ -632,24 +640,49 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis) return *this; } +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +/*! + \overload + + Rotates the coordinate system counterclockwise by the given angle \a a + about the specified \a axis at distance 1024.0 from the screen and + returns a reference to the matrix. + + \include qtransform.cpp transform-rotate-note + + \sa setMatrix +*/ +QTransform &QTransform::rotate(qreal a, Qt::Axis axis) +{ + return rotate(a, axis, 1024.0); +} +#endif + /*! - \fn QTransform & QTransform::rotateRadians(qreal angle, Qt::Axis axis) + \since 6.5 - Rotates the coordinate system counterclockwise by the given \a angle - about the specified \a axis and returns a reference to the matrix. + Rotates the coordinate system counterclockwise by the given angle \a a + about the specified \a axis at distance \a distanceToPlane from the + screen and returns a reference to the matrix. +//! [transform-rotate-radians-note] Note that if you apply a QTransform to a point defined in widget coordinates, the direction of the rotation will be clockwise because the y-axis points downwards. The angle is specified in radians. +//! [transform-rotate-radians-note] + + If \a distanceToPlane is zero, it will be ignored. This is suitable + for implementing orthographic projections where the z coordinate should + be dropped rather than projected. \sa setMatrix() */ -QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis) +QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis, qreal distanceToPlane) { #ifndef QT_NO_DEBUG - if (qIsNaN(a)) { + if (qIsNaN(a) || qIsNaN(distanceToPlane)) { nanWarning("rotateRadians"); return *this; } @@ -700,13 +733,16 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis) if (m_dirty < TxRotate) m_dirty = TxRotate; } else { + if (!qIsNull(distanceToPlane)) + sina /= distanceToPlane; + QTransform result; if (axis == Qt::YAxis) { result.m_matrix[0][0] = cosa; - result.m_matrix[0][2] = -sina * inv_dist_to_plane; + result.m_matrix[0][2] = -sina; } else { result.m_matrix[1][1] = cosa; - result.m_matrix[1][2] = -sina * inv_dist_to_plane; + result.m_matrix[1][2] = -sina; } result.m_type = TxProject; *this = result * *this; @@ -714,6 +750,24 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis) return *this; } +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +/*! + \overload + + Rotates the coordinate system counterclockwise by the given angle \a a + about the specified \a axis at distance 1024.0 from the screen and + returns a reference to the matrix. + + \include qtransform.cpp transform-rotate-radians-note + + \sa setMatrix() +*/ +QTransform &QTransform::rotateRadians(qreal a, Qt::Axis axis) +{ + return rotateRadians(a, axis, 1024.0); +} +#endif + /*! \fn bool QTransform::operator==(const QTransform &matrix) const Returns \c true if this matrix is equal to the given \a matrix, diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 71418935d1..e5b245d8c9 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -84,8 +84,17 @@ public: QTransform &translate(qreal dx, qreal dy); QTransform &scale(qreal sx, qreal sy); QTransform &shear(qreal sh, qreal sv); +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + QTransform &rotate(qreal a, Qt::Axis axis, qreal distanceToPlane); + // ### Qt7: Remove QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis); + QTransform &rotateRadians(qreal a, Qt::Axis axis, qreal distanceToPlane); + // ### Qt7: Remove QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis); +#else + QTransform &rotate(qreal a, Qt::Axis axis = Qt::ZAxis, qreal distanceToPlane = 1024.0f); + QTransform &rotateRadians(qreal a, Qt::Axis axis = Qt::ZAxis, qreal distanceToPlane = 1024.0f); +#endif static bool squareToQuad(const QPolygonF &square, QTransform &result); static bool quadToSquare(const QPolygonF &quad, QTransform &result); |