diff options
author | JiDe Zhang <zhangjide@uniontech.com> | 2022-07-27 18:04:30 +0800 |
---|---|---|
committer | JiDe Zhang <zhangjide@uniontech.com> | 2022-08-18 10:40:42 +0800 |
commit | a6b55b3c46cf47d560e10a4b69db24a475261546 (patch) | |
tree | a7303a6d13a3266d2cc619e33436b6426225c257 /src/gui/painting | |
parent | 371214dea7f92b3170d0239b3d9944275adf951a (diff) |
Allow specify distance to plane for QTransform
The default camera to plane distance is 1024, when rotating a big image
along the x or y axis, some areas of the screen may move above the
camera, causing the rotation to fail. A new rotation interface has been
added to allow users to specify the distance from the camera to the
plane themselves when rotating the QImage. Also, this support has been
added to QMatrix4x4::projectedRotate.
[ChangeLog][QtGui][QTransform] Added overloads to rotate() and
rotateRadians() that allow specifying of the distance to the rotation
plane.
Fixes: QTBUG-105088
Change-Id: I81f629916ddd9b6ab84e0282191e4284a88a85f5
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qtransform.cpp | 86 | ||||
-rw-r--r-- | src/gui/painting/qtransform.h | 9 |
2 files changed, 79 insertions, 16 deletions
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); |