diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-12-01 14:07:26 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2021-02-04 17:18:51 +0100 |
commit | 7a738daa97436478a21b5dd31ba2312b2cb2df41 (patch) | |
tree | 9e4a536302e2c0b212f99031bb017dfb7961effe /src/gui/math3d | |
parent | 96ef1769c18d90053e48176c22a594e03f1d6e38 (diff) |
Make explicit that we expect co-ordinates to be finite
The various spatial-vector, line, point, region and margin types have
all long taken for granted that their co-ordinates are finite and, in
particular, not NaN. Make this expectation explicit in the
documentation. Added assertions where (chiefly) noexcept and (where
the assertion would be a simple qIsFinite() call) constexpr didn't
preclude doing so. Also assert against zero divisors that would lead
to non-finite results.
Make minor clean-ups to docs in the process. QMarginsF had several
methods whose declaration, definition and docs weren't consistent in
their parameter names.
Task-number: QTBUG-89010
Change-Id: I601a830959d13a73dcb17ce31a1202a1486c8f7f
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/gui/math3d')
-rw-r--r-- | src/gui/math3d/qvectornd.cpp | 133 | ||||
-rw-r--r-- | src/gui/math3d/qvectornd.h | 30 |
2 files changed, 111 insertions, 52 deletions
diff --git a/src/gui/math3d/qvectornd.cpp b/src/gui/math3d/qvectornd.cpp index 1c456a9d6d..28e8f9ff67 100644 --- a/src/gui/math3d/qvectornd.cpp +++ b/src/gui/math3d/qvectornd.cpp @@ -56,6 +56,10 @@ QT_BEGIN_NAMESPACE \ingroup painting-3D \inmodule QtGui + Vectors are one of the main building blocks of 2D representation and + drawing. They consist of two finite floating-point coordinates, + traditionally called x and y. + The QVector2D class can also be used to represent vertices in 2D space. We therefore do not need to provide a separate vertex class. @@ -80,6 +84,7 @@ QT_BEGIN_NAMESPACE \fn QVector2D::QVector2D(float xpos, float ypos) Constructs a vector with coordinates (\a xpos, \a ypos). + Both coordinates must be finite. */ /*! @@ -146,7 +151,7 @@ QT_BEGIN_NAMESPACE /*! \fn void QVector2D::setX(float x) - Sets the x coordinate of this point to the given \a x coordinate. + Sets the x coordinate of this point to the given finite \a x coordinate. \sa x(), setY() */ @@ -154,7 +159,7 @@ QT_BEGIN_NAMESPACE /*! \fn void QVector2D::setY(float y) - Sets the y coordinate of this point to the given \a y coordinate. + Sets the y coordinate of this point to the given finite \a y coordinate. \sa y(), setX() */ @@ -260,7 +265,7 @@ QT_BEGIN_NAMESPACE /*! \fn QVector2D &QVector2D::operator*=(float factor) - Multiplies this vector's coordinates by the given \a factor, and + Multiplies this vector's coordinates by the given finite \a factor and returns a reference to this vector. \sa operator/=() @@ -276,8 +281,8 @@ QT_BEGIN_NAMESPACE /*! \fn QVector2D &QVector2D::operator/=(float divisor) - Divides this vector's coordinates by the given \a divisor, and - returns a reference to this vector. + Divides this vector's coordinates by the given \a divisor and returns a + reference to this vector. The \a divisor must not be either zero or NaN. \sa operator*=() */ @@ -286,10 +291,12 @@ QT_BEGIN_NAMESPACE \fn QVector2D &QVector2D::operator/=(QVector2D vector) \since 5.5 - Divides the components of this vector by the corresponding - components in \a vector. + Divides each component of this vector by the corresponding component of \a + vector and returns a reference to this vector. - \sa operator*=() + The \a vector must have no component that is either zero or NaN. + + \sa operator*=(), operator/() */ /*! @@ -333,7 +340,7 @@ QT_BEGIN_NAMESPACE /*! //! friend \fn const QVector2D QVector2D::operator*(float factor, QVector2D vector) - Returns a copy of the given \a vector, multiplied by the given \a factor. + Returns a copy of the given \a vector, multiplied by the given finite \a factor. \sa QVector2D::operator*=() */ @@ -341,7 +348,7 @@ QT_BEGIN_NAMESPACE /*! //! friend \fn const QVector2D QVector2D::operator*(QVector2D vector, float factor) - Returns a copy of the given \a vector, multiplied by the given \a factor. + Returns a copy of the given \a vector, multiplied by the given finite \a factor. \sa QVector2D::operator*=() */ @@ -366,8 +373,10 @@ QT_BEGIN_NAMESPACE /*! //! friend \fn const QVector2D QVector2D::operator/(QVector2D vector, float divisor) - Returns the QVector2D object formed by dividing all three components of - the given \a vector by the given \a divisor. + Returns the QVector2D object formed by dividing each component of the given + \a vector by the given \a divisor. + + The \a divisor must not be either zero or NaN. \sa QVector2D::operator/=() */ @@ -376,8 +385,10 @@ QT_BEGIN_NAMESPACE \fn const QVector2D QVector2D::operator/(QVector2D vector, QVector2D divisor) \since 5.5 - Returns the QVector2D object formed by dividing components of the given - \a vector by a respective components of the given \a divisor. + Returns the QVector2D object formed by dividing each component of the given + \a vector by the corresponding component of the given \a divisor. + + The \a divisor must have no component that is either zero or NaN. \sa QVector2D::operator/=() */ @@ -481,6 +492,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) float x, y; stream >> x; stream >> y; + Q_ASSERT(qIsFinite(x) && qIsFinite(y)); vector.setX(x); vector.setY(y); return stream; @@ -502,8 +514,8 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) \inmodule QtGui Vectors are one of the main building blocks of 3D representation and - drawing. They consist of three coordinates, traditionally called - x, y, and z. + drawing. They consist of three finite floating-point coordinates, + traditionally called x, y, and z. The QVector3D class can also be used to represent vertices in 3D space. We therefore do not need to provide a separate vertex class. @@ -529,6 +541,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) \fn QVector3D::QVector3D(float xpos, float ypos, float zpos) Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos). + All parameters must be finite. */ /*! @@ -560,7 +573,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) \fn QVector3D::QVector3D(QVector2D vector, float zpos) Constructs a 3D vector from the specified 2D \a vector. The z - coordinate is set to \a zpos. + coordinate is set to \a zpos, which must be finite. \sa toVector2D() */ @@ -613,7 +626,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn void QVector3D::setX(float x) - Sets the x coordinate of this point to the given \a x coordinate. + Sets the x coordinate of this point to the given finite \a x coordinate. \sa x(), setY(), setZ() */ @@ -621,7 +634,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn void QVector3D::setY(float y) - Sets the y coordinate of this point to the given \a y coordinate. + Sets the y coordinate of this point to the given finite \a y coordinate. \sa y(), setX(), setZ() */ @@ -629,7 +642,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn void QVector3D::setZ(float z) - Sets the z coordinate of this point to the given \a z coordinate. + Sets the z coordinate of this point to the given finite \a z coordinate. \sa z(), setX(), setY() */ @@ -695,7 +708,7 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn QVector3D &QVector3D::operator*=(float factor) - Multiplies this vector's coordinates by the given \a factor, and + Multiplies this vector's coordinates by the given finite \a factor and returns a reference to this vector. \sa operator/=() @@ -717,8 +730,8 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn QVector3D &QVector3D::operator/=(float divisor) - Divides this vector's coordinates by the given \a divisor, and - returns a reference to this vector. + Divides this vector's coordinates by the given \a divisor, and returns a + reference to this vector. The \a divisor must not be either zero or NaN. \sa operator*=() */ @@ -727,8 +740,10 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) \fn QVector3D &QVector3D::operator/=(QVector3D vector) \since 5.5 - Divides the components of this vector by the corresponding - components in \a vector. + Divides each component of this vector by the corresponding component in \a + vector and returns a reference to this vector. + + The \a vector must have no component that is either zero or NaN. \sa operator*=() */ @@ -751,8 +766,8 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn QVector3D QVector3D::normal(QVector3D v1, QVector3D v2) - Returns the normal vector of a plane defined by vectors \a v1 and \a v2, - normalized to be a unit vector. + Returns the unit normal vector of a plane spanned by vectors \a v1 and \a + v2, which must not be parallel to one another. Use crossProduct() to compute the cross-product of \a v1 and \a v2 if you do not need the result to be normalized to a unit vector. @@ -763,8 +778,8 @@ QDataStream &operator>>(QDataStream &stream, QVector2D &vector) /*! \fn QVector3D QVector3D::normal(QVector3D v1, QVector3D v2, QVector3D v3) - Returns the normal vector of a plane defined by vectors - \a v2 - \a v1 and \a v3 - \a v1, normalized to be a unit vector. + Returns the unit normal vector of a plane spanned by vectors \a v2 - \a v1 + and \a v3 - \a v1, which must not be parallel to one another. Use crossProduct() to compute the cross-product of \a v2 - \a v1 and \a v3 - \a v1 if you do not need the result to be normalized to a @@ -922,7 +937,7 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr /*! //! friend \fn const QVector3D QVector3D::operator*(float factor, QVector3D vector) - Returns a copy of the given \a vector, multiplied by the given \a factor. + Returns a copy of the given \a vector, multiplied by the given finite \a factor. \sa QVector3D::operator*=() */ @@ -930,7 +945,7 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr /*! //! friend \fn const QVector3D QVector3D::operator*(QVector3D vector, float factor) - Returns a copy of the given \a vector, multiplied by the given \a factor. + Returns a copy of the given \a vector, multiplied by the given finite \a factor. \sa QVector3D::operator*=() */ @@ -958,8 +973,10 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr /*! //! friend \fn const QVector3D QVector3D::operator/(QVector3D vector, float divisor) - Returns the QVector3D object formed by dividing all three components of - the given \a vector by the given \a divisor. + Returns the QVector3D object formed by dividing each component of the given + \a vector by the given \a divisor. + + The \a divisor must not be either zero or NaN. \sa QVector3D::operator/=() */ @@ -968,8 +985,10 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr \fn const QVector3D QVector3D::operator/(QVector3D vector, QVector3D divisor) \since 5.5 - Returns the QVector3D object formed by dividing components of the given - \a vector by a respective components of the given \a divisor. + Returns the QVector3D object formed by dividing each component of the given + \a vector by the corresponding component of the given \a divisor. + + The \a divisor must have no component that is either zero or NaN. \sa QVector3D::operator/=() */ @@ -1100,6 +1119,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) stream >> x; stream >> y; stream >> z; + Q_ASSERT(qIsFinite(x) && qIsFinite(y) && qIsFinite(z)); vector.setX(x); vector.setY(y); vector.setZ(z); @@ -1121,6 +1141,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) \ingroup painting-3D \inmodule QtGui + Vectors are one of the main building blocks of 4D affine representations of + 3D space. They consist of four finite floating-point coordinates, + traditionally called x, y, z and w. + The QVector4D class can also be used to represent vertices in 4D space. We therefore do not need to provide a separate vertex class. @@ -1145,6 +1169,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) \fn QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos). + All parameters must be finite. */ /*! @@ -1176,7 +1201,8 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) \fn QVector4D::QVector4D(QVector2D vector, float zpos, float wpos) Constructs a 4D vector from the specified 2D \a vector. The z - and w coordinates are set to \a zpos and \a wpos respectively. + and w coordinates are set to \a zpos and \a wpos respectively, + each of which must be finite. \sa toVector2D() */ @@ -1198,7 +1224,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) \fn QVector4D::QVector4D(QVector3D vector, float wpos) Constructs a 4D vector from the specified 3D \a vector. The w - coordinate is set to \a wpos. + coordinate is set to \a wpos, which must be finite. \sa toVector3D() */ @@ -1247,7 +1273,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! \fn void QVector4D::setX(float x) - Sets the x coordinate of this point to the given \a x coordinate. + Sets the x coordinate of this point to the given finite \a x coordinate. \sa x(), setY(), setZ(), setW() */ @@ -1255,7 +1281,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! \fn void QVector4D::setY(float y) - Sets the y coordinate of this point to the given \a y coordinate. + Sets the y coordinate of this point to the given finite \a y coordinate. \sa y(), setX(), setZ(), setW() */ @@ -1263,7 +1289,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! \fn void QVector4D::setZ(float z) - Sets the z coordinate of this point to the given \a z coordinate. + Sets the z coordinate of this point to the given finite \a z coordinate. \sa z(), setX(), setY(), setW() */ @@ -1271,7 +1297,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! \fn void QVector4D::setW(float w) - Sets the w coordinate of this point to the given \a w coordinate. + Sets the w coordinate of this point to the given finite \a w coordinate. \sa w(), setX(), setY(), setZ() */ @@ -1355,7 +1381,7 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! \fn QVector4D &QVector4D::operator*=(float factor) - Multiplies this vector's coordinates by the given \a factor, and + Multiplies this vector's coordinates by the given finite \a factor, and returns a reference to this vector. \sa operator/=() @@ -1371,8 +1397,8 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! \fn QVector4D &QVector4D::operator/=(float divisor) - Divides this vector's coordinates by the given \a divisor, and - returns a reference to this vector. + Divides this vector's coordinates by the given \a divisor, and returns a + reference to this vector. The \a divisor must not be either zero or NaN. \sa operator*=() */ @@ -1381,8 +1407,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) \fn QVector4D &QVector4D::operator/=(QVector4D vector) \since 5.5 - Divides the components of this vector by the corresponding - components in \a vector. + Divides each component of this vector by the corresponding component of \a + vector and returns a reference to this vector. + + The \a vector must have no component that is either zero or NaN. \sa operator*=() */ @@ -1463,8 +1491,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) /*! //! friend \fn const QVector4D QVector4D::operator/(QVector4D vector, float divisor) - Returns the QVector4D object formed by dividing all four components of - the given \a vector by the given \a divisor. + Returns the QVector4D object formed by dividing each component of the given + \a vector by the given \a divisor. + + The \a divisor must not be either zero or NaN. \sa QVector4D::operator/=() */ @@ -1473,8 +1503,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) \fn const QVector4D QVector4D::operator/(QVector4D vector, QVector4D divisor) \since 5.5 - Returns the QVector4D object formed by dividing components of the given - \a vector by a respective components of the given \a divisor. + Returns the QVector4D object formed by dividing each component of the given + \a vector by the corresponding component of the given \a divisor. + + The \a divisor must have no component that is either zero or NaN. \sa QVector4D::operator/=() */ @@ -1611,6 +1643,7 @@ QDataStream &operator>>(QDataStream &stream, QVector4D &vector) stream >> y; stream >> z; stream >> w; + Q_ASSERT(qIsFinite(x) && qIsFinite(y) && qIsFinite(z) && qIsFinite(w)); vector.setX(x); vector.setY(y); vector.setZ(z); diff --git a/src/gui/math3d/qvectornd.h b/src/gui/math3d/qvectornd.h index 8d2789338c..153f3743d8 100644 --- a/src/gui/math3d/qvectornd.h +++ b/src/gui/math3d/qvectornd.h @@ -147,11 +147,14 @@ QT_WARNING_POP constexpr friend inline QVector2D operator/(QVector2D vector, float divisor) { + Q_ASSERT(divisor < 0 || divisor > 0); return QVector2D(vector.v[0] / divisor, vector.v[1] / divisor); } constexpr friend inline QVector2D operator/(QVector2D vector, QVector2D divisor) { + Q_ASSERT(divisor.v[0] < 0 || divisor.v[0] > 0); + Q_ASSERT(divisor.v[1] < 0 || divisor.v[1] > 0); return QVector2D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1]); } @@ -288,12 +291,17 @@ QT_WARNING_POP constexpr friend inline QVector3D operator/(QVector3D vector, float divisor) { + Q_ASSERT(divisor < 0 || divisor > 0); return QVector3D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor); } constexpr friend inline QVector3D operator/(QVector3D vector, QVector3D divisor) { - return QVector3D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], vector.v[2] / divisor.v[2]); + Q_ASSERT(divisor.v[0] > 0 || divisor.v[0] < 0); + Q_ASSERT(divisor.v[1] > 0 || divisor.v[1] < 0); + Q_ASSERT(divisor.v[2] > 0 || divisor.v[2] < 0); + return QVector3D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], + vector.v[2] / divisor.v[2]); } friend Q_GUI_EXPORT bool qFuzzyCompare(QVector3D v1, QVector3D v2) noexcept; @@ -422,12 +430,18 @@ QT_WARNING_POP constexpr friend inline QVector4D operator/(QVector4D vector, float divisor) { + Q_ASSERT(divisor < 0 || divisor > 0); return QVector4D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor, vector.v[3] / divisor); } constexpr friend inline QVector4D operator/(QVector4D vector, QVector4D divisor) { - return QVector4D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], vector.v[2] / divisor.v[2], vector.v[3] / divisor.v[3]); + Q_ASSERT(divisor.v[0] > 0 || divisor.v[0] < 0); + Q_ASSERT(divisor.v[1] > 0 || divisor.v[1] < 0); + Q_ASSERT(divisor.v[2] > 0 || divisor.v[2] < 0); + Q_ASSERT(divisor.v[3] > 0 || divisor.v[3] < 0); + return QVector4D(vector.v[0] / divisor.v[0], vector.v[1] / divisor.v[1], + vector.v[2] / divisor.v[2], vector.v[3] / divisor.v[3]); } friend Q_GUI_EXPORT bool qFuzzyCompare(QVector4D v1, QVector4D v2) noexcept; @@ -576,6 +590,7 @@ constexpr inline QVector2D &QVector2D::operator*=(QVector2D vector) noexcept constexpr inline QVector2D &QVector2D::operator/=(float divisor) { + Q_ASSERT(divisor < 0 || divisor > 0); v[0] /= divisor; v[1] /= divisor; return *this; @@ -583,6 +598,8 @@ constexpr inline QVector2D &QVector2D::operator/=(float divisor) constexpr inline QVector2D &QVector2D::operator/=(QVector2D vector) { + Q_ASSERT(vector.v[0] > 0 || vector.v[0] < 0); + Q_ASSERT(vector.v[1] > 0 || vector.v[1] < 0); v[0] /= vector.v[0]; v[1] /= vector.v[1]; return *this; @@ -736,6 +753,7 @@ constexpr inline QVector3D &QVector3D::operator*=(QVector3D vector) noexcept constexpr inline QVector3D &QVector3D::operator/=(float divisor) { + Q_ASSERT(divisor < 0 || divisor > 0); v[0] /= divisor; v[1] /= divisor; v[2] /= divisor; @@ -744,6 +762,9 @@ constexpr inline QVector3D &QVector3D::operator/=(float divisor) constexpr inline QVector3D &QVector3D::operator/=(QVector3D vector) { + Q_ASSERT(vector.v[0] > 0 || vector.v[0] < 0); + Q_ASSERT(vector.v[1] > 0 || vector.v[1] < 0); + Q_ASSERT(vector.v[2] > 0 || vector.v[2] < 0); v[0] /= vector.v[0]; v[1] /= vector.v[1]; v[2] /= vector.v[2]; @@ -947,6 +968,7 @@ constexpr inline QVector4D &QVector4D::operator*=(QVector4D vector) noexcept constexpr inline QVector4D &QVector4D::operator/=(float divisor) { + Q_ASSERT(divisor < 0 || divisor > 0); v[0] /= divisor; v[1] /= divisor; v[2] /= divisor; @@ -956,6 +978,10 @@ constexpr inline QVector4D &QVector4D::operator/=(float divisor) constexpr inline QVector4D &QVector4D::operator/=(QVector4D vector) { + Q_ASSERT(vector.v[0] > 0 || vector.v[0] < 0); + Q_ASSERT(vector.v[1] > 0 || vector.v[1] < 0); + Q_ASSERT(vector.v[2] > 0 || vector.v[2] < 0); + Q_ASSERT(vector.v[3] > 0 || vector.v[3] < 0); v[0] /= vector.v[0]; v[1] /= vector.v[1]; v[2] /= vector.v[2]; |