summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2020-12-01 14:07:26 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2021-02-04 17:18:51 +0100
commit7a738daa97436478a21b5dd31ba2312b2cb2df41 (patch)
tree9e4a536302e2c0b212f99031bb017dfb7961effe /src/gui/math3d
parent96ef1769c18d90053e48176c22a594e03f1d6e38 (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.cpp133
-rw-r--r--src/gui/math3d/qvectornd.h30
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];