Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquaternion.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQUATERNION_H
5#define QQUATERNION_H
6
7#include <QtGui/qtguiglobal.h>
8#include <QtGui/qgenericmatrix.h>
9#include <QtGui/qvector3d.h>
10#include <QtGui/qvector4d.h>
11
13
14
15#ifndef QT_NO_QUATERNION
16
17class QMatrix4x4;
18class QVariant;
19
20class Q_GUI_EXPORT QQuaternion
21{
22public:
25 QQuaternion(float scalar, float xpos, float ypos, float zpos);
26#ifndef QT_NO_VECTOR3D
27 QQuaternion(float scalar, const QVector3D& vector);
28#endif
29#ifndef QT_NO_VECTOR4D
30 explicit QQuaternion(const QVector4D& vector);
31#endif
32
33 bool isNull() const;
34 bool isIdentity() const;
35
36#ifndef QT_NO_VECTOR3D
37 QVector3D vector() const;
38 void setVector(const QVector3D& vector);
39#endif
40 void setVector(float x, float y, float z);
41
42 float x() const;
43 float y() const;
44 float z() const;
45 float scalar() const;
46
47 void setX(float x);
48 void setY(float y);
49 void setZ(float z);
50 void setScalar(float scalar);
51
52 constexpr static inline float dotProduct(const QQuaternion &q1, const QQuaternion &q2);
53
54 float length() const;
55 float lengthSquared() const;
56
57 [[nodiscard]] QQuaternion normalized() const;
58 void normalize();
59
60 inline QQuaternion inverted() const;
61
62 [[nodiscard]] QQuaternion conjugated() const;
63
64 QVector3D rotatedVector(const QVector3D& vector) const;
65
66 QQuaternion &operator+=(const QQuaternion &quaternion);
67 QQuaternion &operator-=(const QQuaternion &quaternion);
68 QQuaternion &operator*=(float factor);
69 QQuaternion &operator*=(const QQuaternion &quaternion);
70 QQuaternion &operator/=(float divisor);
71
74 friend inline bool operator==(const QQuaternion &q1, const QQuaternion &q2) noexcept
75 {
76 return q1.wp == q2.wp && q1.xp == q2.xp && q1.yp == q2.yp && q1.zp == q2.zp;
77 }
78 friend inline bool operator!=(const QQuaternion &q1, const QQuaternion &q2) noexcept
79 {
80 return !(q1 == q2);
81 }
83
84 friend inline const QQuaternion operator+(const QQuaternion &q1, const QQuaternion &q2);
85 friend inline const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2);
86 friend inline const QQuaternion operator*(float factor, const QQuaternion &quaternion);
87 friend inline const QQuaternion operator*(const QQuaternion &quaternion, float factor);
88 friend inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2);
89 friend inline const QQuaternion operator-(const QQuaternion &quaternion);
90 friend inline const QQuaternion operator/(const QQuaternion &quaternion, float divisor);
91
92 friend inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2);
93
94#ifndef QT_NO_VECTOR4D
95 QVector4D toVector4D() const;
96#endif
97
98 operator QVariant() const;
99
100#ifndef QT_NO_VECTOR3D
101 inline void getAxisAndAngle(QVector3D *axis, float *angle) const;
102 static QQuaternion fromAxisAndAngle(const QVector3D& axis, float angle);
103#endif
104 void getAxisAndAngle(float *x, float *y, float *z, float *angle) const;
105 static QQuaternion fromAxisAndAngle
106 (float x, float y, float z, float angle);
107
108#ifndef QT_NO_VECTOR3D
109 inline QVector3D toEulerAngles() const;
110 static inline QQuaternion fromEulerAngles(const QVector3D &eulerAngles);
111#endif
112 void getEulerAngles(float *pitch, float *yaw, float *roll) const;
113 static QQuaternion fromEulerAngles(float pitch, float yaw, float roll);
114
115 QMatrix3x3 toRotationMatrix() const;
116 static QQuaternion fromRotationMatrix(const QMatrix3x3 &rot3x3);
117
118#ifndef QT_NO_VECTOR3D
119 void getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const;
120 static QQuaternion fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis);
121
122 static QQuaternion fromDirection(const QVector3D &direction, const QVector3D &up);
123
124 static QQuaternion rotationTo(const QVector3D &from, const QVector3D &to);
125#endif
126
127 static QQuaternion slerp
128 (const QQuaternion& q1, const QQuaternion& q2, float t);
129 static QQuaternion nlerp
130 (const QQuaternion& q1, const QQuaternion& q2, float t);
131
132private:
133 float wp, xp, yp, zp;
134};
135
137
138inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {}
139
140inline QQuaternion::QQuaternion(float aScalar, float xpos, float ypos, float zpos) : wp(aScalar), xp(xpos), yp(ypos), zp(zpos) {}
141
144
145inline bool QQuaternion::isNull() const
146{
147 return wp == 0.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f;
148}
149
150inline bool QQuaternion::isIdentity() const
151{
152 return wp == 1.0f && xp == 0.0f && yp == 0.0f && zp == 0.0f;
153}
155
156inline float QQuaternion::x() const { return xp; }
157inline float QQuaternion::y() const { return yp; }
158inline float QQuaternion::z() const { return zp; }
159inline float QQuaternion::scalar() const { return wp; }
160
161inline void QQuaternion::setX(float aX) { xp = aX; }
162inline void QQuaternion::setY(float aY) { yp = aY; }
163inline void QQuaternion::setZ(float aZ) { zp = aZ; }
164inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; }
165
166constexpr inline float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2)
167{
168 return q1.wp * q2.wp + q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp;
169}
170
172{
173 // Need some extra precision if the length is very small.
174 double len = double(wp) * double(wp) +
175 double(xp) * double(xp) +
176 double(yp) * double(yp) +
177 double(zp) * double(zp);
178 if (!qFuzzyIsNull(len))
179 return QQuaternion(float(double(wp) / len), float(double(-xp) / len),
180 float(double(-yp) / len), float(double(-zp) / len));
181 return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
182}
183
185{
186 return QQuaternion(wp, -xp, -yp, -zp);
187}
188
190{
191 wp += quaternion.wp;
192 xp += quaternion.xp;
193 yp += quaternion.yp;
194 zp += quaternion.zp;
195 return *this;
196}
197
199{
200 wp -= quaternion.wp;
201 xp -= quaternion.xp;
202 yp -= quaternion.yp;
203 zp -= quaternion.zp;
204 return *this;
205}
206
208{
209 wp *= factor;
210 xp *= factor;
211 yp *= factor;
212 zp *= factor;
213 return *this;
214}
215
216inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2)
217{
218 float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp);
219 float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp);
220 float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp);
221 float xx = ww + yy + zz;
222 float qq = 0.5f * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp));
223
224 float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp);
225 float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp);
226 float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp);
227 float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp);
228
229 return QQuaternion(w, x, y, z);
230}
231
233{
234 *this = *this * quaternion;
235 return *this;
236}
237
239{
240 wp /= divisor;
241 xp /= divisor;
242 yp /= divisor;
243 zp /= divisor;
244 return *this;
245}
246
247inline const QQuaternion operator+(const QQuaternion &q1, const QQuaternion &q2)
248{
249 return QQuaternion(q1.wp + q2.wp, q1.xp + q2.xp, q1.yp + q2.yp, q1.zp + q2.zp);
250}
251
252inline const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2)
253{
254 return QQuaternion(q1.wp - q2.wp, q1.xp - q2.xp, q1.yp - q2.yp, q1.zp - q2.zp);
255}
256
257inline const QQuaternion operator*(float factor, const QQuaternion &quaternion)
258{
259 return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor);
260}
261
262inline const QQuaternion operator*(const QQuaternion &quaternion, float factor)
263{
264 return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor);
265}
266
267inline const QQuaternion operator-(const QQuaternion &quaternion)
268{
269 return QQuaternion(-quaternion.wp, -quaternion.xp, -quaternion.yp, -quaternion.zp);
270}
271
272inline const QQuaternion operator/(const QQuaternion &quaternion, float divisor)
273{
274 return QQuaternion(quaternion.wp / divisor, quaternion.xp / divisor, quaternion.yp / divisor, quaternion.zp / divisor);
275}
276
277inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2)
278{
279 return qFuzzyCompare(q1.wp, q2.wp) &&
280 qFuzzyCompare(q1.xp, q2.xp) &&
281 qFuzzyCompare(q1.yp, q2.yp) &&
282 qFuzzyCompare(q1.zp, q2.zp);
283}
284
285#ifndef QT_NO_VECTOR3D
286
287inline QQuaternion::QQuaternion(float aScalar, const QVector3D& aVector)
288 : wp(aScalar), xp(aVector.x()), yp(aVector.y()), zp(aVector.z()) {}
289
290inline void QQuaternion::setVector(const QVector3D& aVector)
291{
292 xp = aVector.x();
293 yp = aVector.y();
294 zp = aVector.z();
295}
296
298{
299 return QVector3D(xp, yp, zp);
300}
301
302inline QVector3D operator*(const QQuaternion &quaternion, const QVector3D &vec)
303{
304 return quaternion.rotatedVector(vec);
305}
306
307inline void QQuaternion::getAxisAndAngle(QVector3D *axis, float *angle) const
308{
309 float aX, aY, aZ;
310 getAxisAndAngle(&aX, &aY, &aZ, angle);
311 *axis = QVector3D(aX, aY, aZ);
312}
313
315{
316 float pitch, yaw, roll;
317 getEulerAngles(&pitch, &yaw, &roll);
318 return QVector3D(pitch, yaw, roll);
319}
320
322{
323 return QQuaternion::fromEulerAngles(eulerAngles.x(), eulerAngles.y(), eulerAngles.z());
324}
325
326#endif
327
328inline void QQuaternion::setVector(float aX, float aY, float aZ)
329{
330 xp = aX;
331 yp = aY;
332 zp = aZ;
333}
334
335#ifndef QT_NO_VECTOR4D
336
338 : wp(aVector.w()), xp(aVector.x()), yp(aVector.y()), zp(aVector.z()) {}
339
341{
342 return QVector4D(xp, yp, zp, wp);
343}
344
345#endif
346
347#ifndef QT_NO_DEBUG_STREAM
348Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QQuaternion &q);
349#endif
350
351#ifndef QT_NO_DATASTREAM
352Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QQuaternion &);
354#endif
355
356#endif
357
359
360#endif
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
The QQuaternion class represents a quaternion consisting of a vector and scalar.
Definition qquaternion.h:21
void getEulerAngles(float *pitch, float *yaw, float *roll) const
QQuaternion conjugated() const
static QQuaternion fromEulerAngles(const QVector3D &eulerAngles)
QQuaternion & operator/=(float divisor)
Divides this quaternion's components by the given divisor, and returns a reference to this quaternion...
QQuaternion()
Constructs an identity quaternion (1, 0, 0, 0), i.e.
QQuaternion & operator-=(const QQuaternion &quaternion)
Subtracts the given quaternion from this quaternion and returns a reference to this quaternion.
QT_WARNING_PUSH QT_WARNING_DISABLE_FLOAT_COMPARE friend bool operator==(const QQuaternion &q1, const QQuaternion &q2) noexcept
Returns true if q1 is equal to q2; otherwise returns false.
Definition qquaternion.h:74
QVector3D vector() const
Returns the vector component of this quaternion.
QQuaternion & operator+=(const QQuaternion &quaternion)
Adds the given quaternion to this quaternion and returns a reference to this quaternion.
void setVector(const QVector3D &vector)
Sets the vector component of this quaternion to vector.
bool isNull() const
Returns true if the x, y, z, and scalar components of this quaternion are set to 0....
bool isIdentity() const
Returns true if the x, y, and z components of this quaternion are set to 0.0, and the scalar componen...
float z() const
Returns the z coordinate of this quaternion's vector.
void setScalar(float scalar)
Sets the scalar component of this quaternion to scalar.
float scalar() const
Returns the scalar component of this quaternion.
QQuaternion & operator*=(float factor)
Multiplies this quaternion's components by the given factor, and returns a reference to this quaterni...
void getAxisAndAngle(QVector3D *axis, float *angle) const
void setX(float x)
Sets the x coordinate of this quaternion's vector to the given x coordinate.
QVector4D toVector4D() const
Returns this quaternion as a 4D vector.
void setZ(float z)
Sets the z coordinate of this quaternion's vector to the given z coordinate.
float x() const
Returns the x coordinate of this quaternion's vector.
float y() const
Returns the y coordinate of this quaternion's vector.
static constexpr float dotProduct(const QQuaternion &q1, const QQuaternion &q2)
void setY(float y)
Sets the y coordinate of this quaternion's vector to the given y coordinate.
friend bool operator!=(const QQuaternion &q1, const QQuaternion &q2) noexcept
Returns true if q1 is not equal to q2; otherwise returns false.
Definition qquaternion.h:78
QQuaternion inverted() const
QQuaternion(Qt::Initialization)
Definition qquaternion.h:24
QVector3D rotatedVector(const QVector3D &vector) const
Rotates vector with this quaternion to produce a new vector in 3D space.
QVector3D toEulerAngles() const
\inmodule QtCore
Definition qvariant.h:64
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
constexpr float y() const noexcept
Returns the y coordinate of this point.
Definition qvectornd.h:671
constexpr float x() const noexcept
Returns the x coordinate of this point.
Definition qvectornd.h:670
constexpr float z() const noexcept
Returns the z coordinate of this point.
Definition qvectornd.h:672
The QVector4D class represents a vector or vertex in 4D space.
Definition qvectornd.h:330
direction
Combined button and popup list for selecting options.
Initialization
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_FLOAT_COMPARE
#define QT_WARNING_PUSH
constexpr timespec operator+(const timespec &t1, const timespec &t2)
constexpr timespec operator*(const timespec &t1, int mul)
constexpr timespec & operator+=(timespec &t1, const timespec &t2)
constexpr timespec operator-(const timespec &t1, const timespec &t2)
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
constexpr QMargins operator/(const QMargins &margins, int divisor)
Definition qmargins.h:189
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLuint divisor
GLenum GLuint GLenum GLsizei length
GLfloat angle
GLint y
GLenum GLsizei len
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLint GLenum GLboolean normalized
Definition qopenglext.h:752
static void normalize(double &x, double &y)
const QQuaternion operator+(const QQuaternion &q1, const QQuaternion &q2)
const QQuaternion operator/(const QQuaternion &quaternion, float divisor)
bool qFuzzyCompare(const QQuaternion &q1, const QQuaternion &q2)
const QQuaternion operator*(const QQuaternion &q1, const QQuaternion &q2)
const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2)
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QQuaternion &q)
Q_GUI_EXPORT QDataStream & operator>>(QDataStream &, QQuaternion &)
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:144
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
QList< int > vector
[14]
p setX(p.x()+1)