1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtGui module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #ifndef QVECTOR4D_H |
41 | #define QVECTOR4D_H |
42 | |
43 | #include <QtGui/qtguiglobal.h> |
44 | #include <QtCore/qpoint.h> |
45 | #include <QtCore/qmetatype.h> |
46 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | |
50 | class QMatrix4x4; |
51 | class QVector2D; |
52 | class QVector3D; |
53 | |
54 | #ifndef QT_NO_VECTOR4D |
55 | |
56 | class Q_GUI_EXPORT QVector4D |
57 | { |
58 | public: |
59 | constexpr QVector4D(); |
60 | explicit QVector4D(Qt::Initialization) {} |
61 | constexpr QVector4D(float xpos, float ypos, float zpos, float wpos); |
62 | constexpr explicit QVector4D(const QPoint& point); |
63 | constexpr explicit QVector4D(const QPointF& point); |
64 | #ifndef QT_NO_VECTOR2D |
65 | QVector4D(const QVector2D& vector); |
66 | QVector4D(const QVector2D& vector, float zpos, float wpos); |
67 | #endif |
68 | #ifndef QT_NO_VECTOR3D |
69 | QVector4D(const QVector3D& vector); |
70 | QVector4D(const QVector3D& vector, float wpos); |
71 | #endif |
72 | |
73 | bool isNull() const; |
74 | |
75 | constexpr float x() const; |
76 | constexpr float y() const; |
77 | constexpr float z() const; |
78 | constexpr float w() const; |
79 | |
80 | void setX(float x); |
81 | void setY(float y); |
82 | void setZ(float z); |
83 | void setW(float w); |
84 | |
85 | float &operator[](int i); |
86 | float operator[](int i) const; |
87 | |
88 | float length() const; |
89 | float lengthSquared() const; //In Qt 6 convert to inline and constexpr |
90 | |
91 | [[nodiscard]] QVector4D normalized() const; |
92 | void normalize(); |
93 | |
94 | QVector4D &operator+=(const QVector4D &vector); |
95 | QVector4D &operator-=(const QVector4D &vector); |
96 | QVector4D &operator*=(float factor); |
97 | QVector4D &operator*=(const QVector4D &vector); |
98 | QVector4D &operator/=(float divisor); |
99 | inline QVector4D &operator/=(const QVector4D &vector); |
100 | |
101 | static float dotProduct(const QVector4D& v1, const QVector4D& v2); //In Qt 6 convert to inline and constexpr |
102 | |
103 | constexpr friend inline bool operator==(const QVector4D &v1, const QVector4D &v2); |
104 | constexpr friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2); |
105 | constexpr friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2); |
106 | constexpr friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2); |
107 | constexpr friend inline const QVector4D operator*(float factor, const QVector4D &vector); |
108 | constexpr friend inline const QVector4D operator*(const QVector4D &vector, float factor); |
109 | constexpr friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2); |
110 | constexpr friend inline const QVector4D operator-(const QVector4D &vector); |
111 | constexpr friend inline const QVector4D operator/(const QVector4D &vector, float divisor); |
112 | constexpr friend inline const QVector4D operator/(const QVector4D &vector, const QVector4D &divisor); |
113 | |
114 | constexpr friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2); |
115 | |
116 | #ifndef QT_NO_VECTOR2D |
117 | QVector2D toVector2D() const; |
118 | QVector2D toVector2DAffine() const; |
119 | #endif |
120 | #ifndef QT_NO_VECTOR3D |
121 | QVector3D toVector3D() const; |
122 | QVector3D toVector3DAffine() const; |
123 | #endif |
124 | |
125 | constexpr QPoint toPoint() const; |
126 | constexpr QPointF toPointF() const; |
127 | |
128 | operator QVariant() const; |
129 | |
130 | private: |
131 | float v[4]; |
132 | |
133 | friend class QVector2D; |
134 | friend class QVector3D; |
135 | #ifndef QT_NO_MATRIX4X4 |
136 | friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix); |
137 | friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector); |
138 | #endif |
139 | }; |
140 | |
141 | Q_DECLARE_TYPEINFO(QVector4D, Q_PRIMITIVE_TYPE); |
142 | |
143 | constexpr inline QVector4D::QVector4D() : v{0.0f, 0.0f, 0.0f, 0.0f} {} |
144 | |
145 | constexpr inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : v{xpos, ypos, zpos, wpos} {} |
146 | |
147 | constexpr inline QVector4D::QVector4D(const QPoint& point) : v{float(point.x()), float(point.y()), 0.0f, 0.0f} {} |
148 | |
149 | constexpr inline QVector4D::QVector4D(const QPointF& point) : v{float(point.x()), float(point.y()), 0.0f, 0.0f} {} |
150 | |
151 | inline bool QVector4D::isNull() const |
152 | { |
153 | return qIsNull(v[0]) && qIsNull(v[1]) && qIsNull(v[2]) && qIsNull(v[3]); |
154 | } |
155 | |
156 | constexpr inline float QVector4D::x() const { return v[0]; } |
157 | constexpr inline float QVector4D::y() const { return v[1]; } |
158 | constexpr inline float QVector4D::z() const { return v[2]; } |
159 | constexpr inline float QVector4D::w() const { return v[3]; } |
160 | |
161 | inline void QVector4D::setX(float aX) { v[0] = aX; } |
162 | inline void QVector4D::setY(float aY) { v[1] = aY; } |
163 | inline void QVector4D::setZ(float aZ) { v[2] = aZ; } |
164 | inline void QVector4D::setW(float aW) { v[3] = aW; } |
165 | |
166 | inline float &QVector4D::operator[](int i) |
167 | { |
168 | Q_ASSERT(uint(i) < 4u); |
169 | return v[i]; |
170 | } |
171 | |
172 | inline float QVector4D::operator[](int i) const |
173 | { |
174 | Q_ASSERT(uint(i) < 4u); |
175 | return v[i]; |
176 | } |
177 | |
178 | inline QVector4D &QVector4D::operator+=(const QVector4D &vector) |
179 | { |
180 | v[0] += vector.v[0]; |
181 | v[1] += vector.v[1]; |
182 | v[2] += vector.v[2]; |
183 | v[3] += vector.v[3]; |
184 | return *this; |
185 | } |
186 | |
187 | inline QVector4D &QVector4D::operator-=(const QVector4D &vector) |
188 | { |
189 | v[0] -= vector.v[0]; |
190 | v[1] -= vector.v[1]; |
191 | v[2] -= vector.v[2]; |
192 | v[3] -= vector.v[3]; |
193 | return *this; |
194 | } |
195 | |
196 | inline QVector4D &QVector4D::operator*=(float factor) |
197 | { |
198 | v[0] *= factor; |
199 | v[1] *= factor; |
200 | v[2] *= factor; |
201 | v[3] *= factor; |
202 | return *this; |
203 | } |
204 | |
205 | inline QVector4D &QVector4D::operator*=(const QVector4D &vector) |
206 | { |
207 | v[0] *= vector.v[0]; |
208 | v[1] *= vector.v[1]; |
209 | v[2] *= vector.v[2]; |
210 | v[3] *= vector.v[3]; |
211 | return *this; |
212 | } |
213 | |
214 | inline QVector4D &QVector4D::operator/=(float divisor) |
215 | { |
216 | v[0] /= divisor; |
217 | v[1] /= divisor; |
218 | v[2] /= divisor; |
219 | v[3] /= divisor; |
220 | return *this; |
221 | } |
222 | |
223 | inline QVector4D &QVector4D::operator/=(const QVector4D &vector) |
224 | { |
225 | v[0] /= vector.v[0]; |
226 | v[1] /= vector.v[1]; |
227 | v[2] /= vector.v[2]; |
228 | v[3] /= vector.v[3]; |
229 | return *this; |
230 | } |
231 | |
232 | QT_WARNING_PUSH |
233 | QT_WARNING_DISABLE_FLOAT_COMPARE |
234 | |
235 | constexpr inline bool operator==(const QVector4D &v1, const QVector4D &v2) |
236 | { |
237 | return v1.v[0] == v2.v[0] && v1.v[1] == v2.v[1] && v1.v[2] == v2.v[2] && v1.v[3] == v2.v[3]; |
238 | } |
239 | |
240 | constexpr inline bool operator!=(const QVector4D &v1, const QVector4D &v2) |
241 | { |
242 | return v1.v[0] != v2.v[0] || v1.v[1] != v2.v[1] || v1.v[2] != v2.v[2] || v1.v[3] != v2.v[3]; |
243 | } |
244 | QT_WARNING_POP |
245 | |
246 | constexpr inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2) |
247 | { |
248 | return QVector4D(v1.v[0] + v2.v[0], v1.v[1] + v2.v[1], v1.v[2] + v2.v[2], v1.v[3] + v2.v[3]); |
249 | } |
250 | |
251 | constexpr inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2) |
252 | { |
253 | return QVector4D(v1.v[0] - v2.v[0], v1.v[1] - v2.v[1], v1.v[2] - v2.v[2], v1.v[3] - v2.v[3]); |
254 | } |
255 | |
256 | constexpr inline const QVector4D operator*(float factor, const QVector4D &vector) |
257 | { |
258 | return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor); |
259 | } |
260 | |
261 | constexpr inline const QVector4D operator*(const QVector4D &vector, float factor) |
262 | { |
263 | return QVector4D(vector.v[0] * factor, vector.v[1] * factor, vector.v[2] * factor, vector.v[3] * factor); |
264 | } |
265 | |
266 | constexpr inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2) |
267 | { |
268 | return QVector4D(v1.v[0] * v2.v[0], v1.v[1] * v2.v[1], v1.v[2] * v2.v[2], v1.v[3] * v2.v[3]); |
269 | } |
270 | |
271 | constexpr inline const QVector4D operator-(const QVector4D &vector) |
272 | { |
273 | return QVector4D(-vector.v[0], -vector.v[1], -vector.v[2], -vector.v[3]); |
274 | } |
275 | |
276 | constexpr inline const QVector4D operator/(const QVector4D &vector, float divisor) |
277 | { |
278 | return QVector4D(vector.v[0] / divisor, vector.v[1] / divisor, vector.v[2] / divisor, vector.v[3] / divisor); |
279 | } |
280 | |
281 | constexpr inline const QVector4D operator/(const QVector4D &vector, const QVector4D &divisor) |
282 | { |
283 | 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]); |
284 | } |
285 | |
286 | constexpr inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2) |
287 | { |
288 | return qFuzzyCompare(v1.v[0], v2.v[0]) && |
289 | qFuzzyCompare(v1.v[1], v2.v[1]) && |
290 | qFuzzyCompare(v1.v[2], v2.v[2]) && |
291 | qFuzzyCompare(v1.v[3], v2.v[3]); |
292 | } |
293 | |
294 | constexpr inline QPoint QVector4D::toPoint() const |
295 | { |
296 | return QPoint(qRound(v[0]), qRound(v[1])); |
297 | } |
298 | |
299 | constexpr inline QPointF QVector4D::toPointF() const |
300 | { |
301 | return QPointF(qreal(v[0]), qreal(v[1])); |
302 | } |
303 | |
304 | #ifndef QT_NO_DEBUG_STREAM |
305 | Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QVector4D &vector); |
306 | #endif |
307 | |
308 | #ifndef QT_NO_DATASTREAM |
309 | Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QVector4D &); |
310 | Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector4D &); |
311 | #endif |
312 | |
313 | #endif |
314 | |
315 | QT_END_NAMESPACE |
316 | |
317 | #endif |
318 | |