Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgenericmatrix.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// Qt-Security score:significant reason:default
4
5#ifndef QGENERICMATRIX_H
6#define QGENERICMATRIX_H
7
8#include <QtGui/qtguiglobal.h>
9#include <QtCore/qmetatype.h>
10#include <QtCore/qdebug.h>
11#include <QtCore/qdatastream.h>
12
13QT_BEGIN_NAMESPACE
14
15
16template <int N, int M, typename T>
17class QGenericMatrix
18{
19public:
20 QGenericMatrix();
21 explicit QGenericMatrix(Qt::Initialization) {}
22 explicit QGenericMatrix(const T *values);
23
24 const T& operator()(int row, int column) const;
25 T& operator()(int row, int column);
26
27 bool isIdentity() const;
28 void setToIdentity();
29
30 void fill(T value);
31
32 [[nodiscard]] QGenericMatrix<M, N, T> transposed() const;
33
34 QGenericMatrix<N, M, T>& operator+=(const QGenericMatrix<N, M, T>& other);
35 QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other);
36 QGenericMatrix<N, M, T>& operator*=(T factor);
37 QGenericMatrix<N, M, T>& operator/=(T divisor);
38 bool operator==(const QGenericMatrix<N, M, T>& other) const;
39 bool operator!=(const QGenericMatrix<N, M, T>& other) const;
40
41 void copyDataTo(T *values) const;
42
43 T *data() { return *m; }
44 const T *data() const { return *m; }
45 const T *constData() const { return *m; }
46
47 template<int NN, int MM, typename TT>
48 friend QGenericMatrix<NN, MM, TT> operator+(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
49 template<int NN, int MM, typename TT>
50 friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
51 template<int NN, int M1, int M2, typename TT>
52 friend QGenericMatrix<M1, M2, TT> operator*(const QGenericMatrix<NN, M2, TT>& m1, const QGenericMatrix<M1, NN, TT>& m2);
53 template<int NN, int MM, typename TT>
54 friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& matrix);
55 template<int NN, int MM, typename TT>
56 friend QGenericMatrix<NN, MM, TT> operator*(TT factor, const QGenericMatrix<NN, MM, TT>& matrix);
57 template<int NN, int MM, typename TT>
58 friend QGenericMatrix<NN, MM, TT> operator*(const QGenericMatrix<NN, MM, TT>& matrix, TT factor);
59 template<int NN, int MM, typename TT>
60 friend QGenericMatrix<NN, MM, TT> operator/(const QGenericMatrix<NN, MM, TT>& matrix, TT divisor);
61
62private:
63 T m[N][M]; // Column-major order to match OpenGL.
64
65 template <int NN, int MM, typename TT>
66 friend class QGenericMatrix;
67};
68template <int N, int M, typename T>
70 : public QTypeInfoMerger<QGenericMatrix<N, M, T>, T>
71{
72};
73
74template <int N, int M, typename T>
75Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
76{
77 setToIdentity();
78}
79
80template <int N, int M, typename T>
81Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values)
82{
83 for (int col = 0; col < N; ++col)
84 for (int row = 0; row < M; ++row)
85 m[col][row] = values[row * N + col];
86}
87
88template <int N, int M, typename T>
89Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const
90{
91 Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
92 return m[column][row];
93}
94
95template <int N, int M, typename T>
96Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column)
97{
98 Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
99 return m[column][row];
100}
101
102template <int N, int M, typename T>
103Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
104{
105 for (int col = 0; col < N; ++col) {
106 for (int row = 0; row < M; ++row) {
107 if (row == col) {
108 if (m[col][row] != 1.0f)
109 return false;
110 } else {
111 if (m[col][row] != 0.0f)
112 return false;
113 }
114 }
115 }
116 return true;
117}
118
119template <int N, int M, typename T>
120Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
121{
122 for (int col = 0; col < N; ++col) {
123 for (int row = 0; row < M; ++row) {
124 if (row == col)
125 m[col][row] = 1.0f;
126 else
127 m[col][row] = 0.0f;
128 }
129 }
130}
131
132template <int N, int M, typename T>
133Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value)
134{
135 for (int col = 0; col < N; ++col)
136 for (int row = 0; row < M; ++row)
137 m[col][row] = value;
138}
139
140template <int N, int M, typename T>
141Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T> QGenericMatrix<N, M, T>::transposed() const
142{
143 QGenericMatrix<M, N, T> result(Qt::Uninitialized);
144 for (int row = 0; row < M; ++row)
145 for (int col = 0; col < N; ++col)
146 result.m[row][col] = m[col][row];
147 return result;
148}
149
150template <int N, int M, typename T>
151Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator+=(const QGenericMatrix<N, M, T>& other)
152{
153 for (int row = 0; row < M; ++row)
154 for (int col = 0; col < N; ++col)
155 m[col][row] += other.m[col][row];
156 return *this;
158
159template <int N, int M, typename T>
160Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other)
161{
162 for (int row = 0; row < M; ++row)
163 for (int col = 0; col < N; ++col)
164 m[col][row] -= other.m[col][row];
165 return *this;
166}
167
168template <int N, int M, typename T>
169Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor)
170{
171 for (int row = 0; row < M; ++row)
172 for (int col = 0; col < N; ++col)
173 m[col][row] *= factor;
174 return *this;
175}
176
177QT_WARNING_PUSH
178QT_WARNING_DISABLE_FLOAT_COMPARE
179
180template <int N, int M, typename T>
181Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
182{
183 for (int row = 0; row < M; ++row)
184 for (int col = 0; col < N; ++col) {
185 if (m[col][row] != other.m[col][row])
186 return false;
187 }
188 return true;
189}
190
191template <int N, int M, typename T>
192Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
193{
194 return !(*this == other);
195}
196
197QT_WARNING_POP
198
199template <int N, int M, typename T>
200Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor)
201{
202 for (int row = 0; row < M; ++row)
203 for (int col = 0; col < N; ++col)
204 m[col][row] /= divisor;
205 return *this;
206}
207
208template <int N, int M, typename T>
209Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
210{
211 QGenericMatrix<N, M, T> result(Qt::Uninitialized);
212 for (int row = 0; row < M; ++row)
213 for (int col = 0; col < N; ++col)
214 result.m[col][row] = m1.m[col][row] + m2.m[col][row];
215 return result;
216}
217
218template <int N, int M, typename T>
219Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
220{
221 QGenericMatrix<N, M, T> result(Qt::Uninitialized);
222 for (int row = 0; row < M; ++row)
223 for (int col = 0; col < N; ++col)
224 result.m[col][row] = m1.m[col][row] - m2.m[col][row];
225 return result;
226}
227
228template <int N, int M1, int M2, typename T>
229Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2)
230{
231 QGenericMatrix<M1, M2, T> result(Qt::Uninitialized);
232 for (int row = 0; row < M2; ++row) {
233 for (int col = 0; col < M1; ++col) {
234 T sum(0.0f);
235 for (int j = 0; j < N; ++j)
236 sum += m1.m[j][row] * m2.m[col][j];
237 result.m[col][row] = sum;
238 }
239 }
240 return result;
241}
242
243template <int N, int M, typename T>
244Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix)
245{
246 QGenericMatrix<N, M, T> result(Qt::Uninitialized);
247 for (int row = 0; row < M; ++row)
248 for (int col = 0; col < N; ++col)
249 result.m[col][row] = -matrix.m[col][row];
250 return result;
251}
253template <int N, int M, typename T>
254Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
255{
256 QGenericMatrix<N, M, T> result(Qt::Uninitialized);
257 for (int row = 0; row < M; ++row)
258 for (int col = 0; col < N; ++col)
259 result.m[col][row] = matrix.m[col][row] * factor;
260 return result;
262
263template <int N, int M, typename T>
264Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
265{
266 QGenericMatrix<N, M, T> result(Qt::Uninitialized);
267 for (int row = 0; row < M; ++row)
268 for (int col = 0; col < N; ++col)
269 result.m[col][row] = matrix.m[col][row] * factor;
270 return result;
271}
272
273template <int N, int M, typename T>
274Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor)
275{
276 QGenericMatrix<N, M, T> result(Qt::Uninitialized);
277 for (int row = 0; row < M; ++row)
278 for (int col = 0; col < N; ++col)
279 result.m[col][row] = matrix.m[col][row] / divisor;
280 return result;
281}
282
283template <int N, int M, typename T>
284Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
285{
286 for (int col = 0; col < N; ++col)
287 for (int row = 0; row < M; ++row)
288 values[row * N + col] = T(m[col][row]);
289}
290
291// Define aliases for the useful variants of QGenericMatrix.
292typedef QGenericMatrix<2, 2, float> QMatrix2x2;
293typedef QGenericMatrix<2, 3, float> QMatrix2x3;
294typedef QGenericMatrix<2, 4, float> QMatrix2x4;
295typedef QGenericMatrix<3, 2, float> QMatrix3x2;
296typedef QGenericMatrix<3, 3, float> QMatrix3x3;
297typedef QGenericMatrix<3, 4, float> QMatrix3x4;
298typedef QGenericMatrix<4, 2, float> QMatrix4x2;
299typedef QGenericMatrix<4, 3, float> QMatrix4x3;
300
301#ifndef QT_NO_DEBUG_STREAM
302
303template <int N, int M, typename T>
304QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
305{
306 QDebugStateSaver saver(dbg);
307 dbg.nospace() << "QGenericMatrix<" << N << ", " << M
308 << ", " << QMetaType::fromType<T>().name()
309 << ">(" << Qt::endl << qSetFieldWidth(10);
310 for (int row = 0; row < M; ++row) {
311 for (int col = 0; col < N; ++col)
312 dbg << m(row, col);
313 dbg << Qt::endl;
314 }
315 dbg << qSetFieldWidth(0) << ')';
316 return dbg;
317}
318
319#endif
320
321#ifndef QT_NO_DATASTREAM
322
323template <int N, int M, typename T>
324QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
325{
326 for (int row = 0; row < M; ++row)
327 for (int col = 0; col < N; ++col)
328 stream << double(matrix(row, col));
329 return stream;
330}
331
332template <int N, int M, typename T>
333QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
334{
335 double x;
336 for (int row = 0; row < M; ++row) {
337 for (int col = 0; col < N; ++col) {
338 stream >> x;
339 matrix(row, col) = T(x);
340 }
341 }
342 return stream;
343}
344
345#endif
346
347QT_END_NAMESPACE
348
349QT_DECL_METATYPE_EXTERN(QMatrix2x2, Q_GUI_EXPORT)
350QT_DECL_METATYPE_EXTERN(QMatrix2x3, Q_GUI_EXPORT)
351QT_DECL_METATYPE_EXTERN(QMatrix2x4, Q_GUI_EXPORT)
352QT_DECL_METATYPE_EXTERN(QMatrix3x2, Q_GUI_EXPORT)
353QT_DECL_METATYPE_EXTERN(QMatrix3x3, Q_GUI_EXPORT)
354QT_DECL_METATYPE_EXTERN(QMatrix3x4, Q_GUI_EXPORT)
355QT_DECL_METATYPE_EXTERN(QMatrix4x2, Q_GUI_EXPORT)
356QT_DECL_METATYPE_EXTERN(QMatrix4x3, Q_GUI_EXPORT)
357
358#endif
QGenericMatrix< 3, 2, float > QMatrix3x2
QDataStream & operator<<(QDataStream &stream, const QGenericMatrix< N, M, T > &matrix)
QGenericMatrix< 2, 2, float > QMatrix2x2
QGenericMatrix< 4, 2, float > QMatrix4x2
QGenericMatrix< 2, 3, float > QMatrix2x3
QGenericMatrix< 3, 4, float > QMatrix3x4
QGenericMatrix< 2, 4, float > QMatrix2x4
QDebug operator<<(QDebug dbg, const QGenericMatrix< N, M, T > &m)
QGenericMatrix< 4, 3, float > QMatrix4x3
QGenericMatrix< 3, 3, float > QMatrix3x3
QDataStream & operator>>(QDataStream &stream, QGenericMatrix< N, M, T > &matrix)