QtGui/qgenericmatrix.h Source File

qgenericmatrix.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QGENERICMATRIX_H
43 #define QGENERICMATRIX_H
44 
45 #include <QtCore/qmetatype.h>
46 #include <QtCore/qdebug.h>
47 #include <QtCore/qdatastream.h>
48 
50 
52 
53 QT_MODULE(Gui)
54 
55 template <int N, int M, typename T>
57 {
58 public:
59  QGenericMatrix();
60  QGenericMatrix(const QGenericMatrix<N, M, T>& other);
61  explicit QGenericMatrix(const T *values);
62 
63  const T& operator()(int row, int column) const;
64  T& operator()(int row, int column);
65 
66  bool isIdentity() const;
67  void setToIdentity();
68 
69  void fill(T value);
70 
71  QGenericMatrix<M, N, T> transposed() const;
72 
74  QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other);
75  QGenericMatrix<N, M, T>& operator*=(T factor);
76  QGenericMatrix<N, M, T>& operator/=(T divisor);
77  bool operator==(const QGenericMatrix<N, M, T>& other) const;
78  bool operator!=(const QGenericMatrix<N, M, T>& other) const;
79 
80  void copyDataTo(T *values) const;
81 
82  T *data() { return *m; }
83  const T *data() const { return *m; }
84  const T *constData() const { return *m; }
85 
86 #if !defined(Q_NO_TEMPLATE_FRIENDS)
87  template<int NN, int MM, typename TT>
89  template<int NN, int MM, typename TT>
91  template<int NN, int M1, int M2, typename TT>
93  template<int NN, int MM, typename TT>
95  template<int NN, int MM, typename TT>
97  template<int NN, int MM, typename TT>
99  template<int NN, int MM, typename TT>
101 
102 private:
103 #endif
104  T m[N][M]; // Column-major order to match OpenGL.
105 
106  QGenericMatrix(int) {} // Construct without initializing identity matrix.
107 
108 #if !defined(Q_NO_TEMPLATE_FRIENDS)
109  template <int NN, int MM, typename TT>
110  friend class QGenericMatrix;
111 #endif
112 };
113 
114 template <int N, int M, typename T>
116 {
117  setToIdentity();
118 }
119 
120 template <int N, int M, typename T>
122 {
123  for (int col = 0; col < N; ++col)
124  for (int row = 0; row < M; ++row)
125  m[col][row] = other.m[col][row];
126 }
127 
128 template <int N, int M, typename T>
129 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values)
130 {
131  for (int col = 0; col < N; ++col)
132  for (int row = 0; row < M; ++row)
133  m[col][row] = values[row * N + col];
134 }
135 
136 template <int N, int M, typename T>
137 Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const
138 {
139  Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
140  return m[column][row];
141 }
142 
143 template <int N, int M, typename T>
144 Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column)
145 {
146  Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
147  return m[column][row];
148 }
149 
150 template <int N, int M, typename T>
151 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
152 {
153  for (int col = 0; col < N; ++col) {
154  for (int row = 0; row < M; ++row) {
155  if (row == col) {
156  if (m[col][row] != 1.0f)
157  return false;
158  } else {
159  if (m[col][row] != 0.0f)
160  return false;
161  }
162  }
163  }
164  return true;
165 }
166 
167 template <int N, int M, typename T>
168 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
169 {
170  for (int col = 0; col < N; ++col) {
171  for (int row = 0; row < M; ++row) {
172  if (row == col)
173  m[col][row] = 1.0f;
174  else
175  m[col][row] = 0.0f;
176  }
177  }
178 }
179 
180 template <int N, int M, typename T>
181 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value)
182 {
183  for (int col = 0; col < N; ++col)
184  for (int row = 0; row < M; ++row)
185  m[col][row] = value;
186 }
187 
188 template <int N, int M, typename T>
190 {
191  QGenericMatrix<M, N, T> result(1);
192  for (int row = 0; row < M; ++row)
193  for (int col = 0; col < N; ++col)
194  result.m[row][col] = m[col][row];
195  return result;
196 }
197 
198 template <int N, int M, typename T>
200 {
201  for (int row = 0; row < M; ++row)
202  for (int col = 0; col < N; ++col)
203  m[col][row] += other.m[col][row];
204  return *this;
205 }
206 
207 template <int N, int M, typename T>
209 {
210  for (int row = 0; row < M; ++row)
211  for (int col = 0; col < N; ++col)
212  m[col][row] -= other.m[col][row];
213  return *this;
214 }
215 
216 template <int N, int M, typename T>
218 {
219  for (int row = 0; row < M; ++row)
220  for (int col = 0; col < N; ++col)
221  m[col][row] *= factor;
222  return *this;
223 }
224 
225 template <int N, int M, typename T>
226 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
227 {
228  for (int row = 0; row < M; ++row)
229  for (int col = 0; col < N; ++col) {
230  if (m[col][row] != other.m[col][row])
231  return false;
232  }
233  return true;
234 }
235 
236 template <int N, int M, typename T>
237 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
238 {
239  for (int row = 0; row < M; ++row)
240  for (int col = 0; col < N; ++col) {
241  if (m[col][row] != other.m[col][row])
242  return true;
243  }
244  return false;
245 }
246 
247 template <int N, int M, typename T>
249 {
250  for (int row = 0; row < M; ++row)
251  for (int col = 0; col < N; ++col)
252  m[col][row] /= divisor;
253  return *this;
254 }
255 
256 template <int N, int M, typename T>
258 {
259  QGenericMatrix<N, M, T> result(1);
260  for (int row = 0; row < M; ++row)
261  for (int col = 0; col < N; ++col)
262  result.m[col][row] = m1.m[col][row] + m2.m[col][row];
263  return result;
264 }
265 
266 template <int N, int M, typename T>
268 {
269  QGenericMatrix<N, M, T> result(1);
270  for (int row = 0; row < M; ++row)
271  for (int col = 0; col < N; ++col)
272  result.m[col][row] = m1.m[col][row] - m2.m[col][row];
273  return result;
274 }
275 
276 template <int N, int M1, int M2, typename T>
278 {
279  QGenericMatrix<M1, M2, T> result(1);
280  for (int row = 0; row < M2; ++row) {
281  for (int col = 0; col < M1; ++col) {
282  T sum(0.0f);
283  for (int j = 0; j < N; ++j)
284  sum += m1.m[j][row] * m2.m[col][j];
285  result.m[col][row] = sum;
286  }
287  }
288  return result;
289 }
290 
291 template <int N, int M, typename T>
293 {
294  QGenericMatrix<N, M, T> result(1);
295  for (int row = 0; row < M; ++row)
296  for (int col = 0; col < N; ++col)
297  result.m[col][row] = -matrix.m[col][row];
298  return result;
299 }
300 
301 template <int N, int M, typename T>
302 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
303 {
304  QGenericMatrix<N, M, T> result(1);
305  for (int row = 0; row < M; ++row)
306  for (int col = 0; col < N; ++col)
307  result.m[col][row] = matrix.m[col][row] * factor;
308  return result;
309 }
310 
311 template <int N, int M, typename T>
312 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
313 {
314  QGenericMatrix<N, M, T> result(1);
315  for (int row = 0; row < M; ++row)
316  for (int col = 0; col < N; ++col)
317  result.m[col][row] = matrix.m[col][row] * factor;
318  return result;
319 }
320 
321 template <int N, int M, typename T>
323 {
324  QGenericMatrix<N, M, T> result(1);
325  for (int row = 0; row < M; ++row)
326  for (int col = 0; col < N; ++col)
327  result.m[col][row] = matrix.m[col][row] / divisor;
328  return result;
329 }
330 
331 template <int N, int M, typename T>
332 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
333 {
334  for (int col = 0; col < N; ++col)
335  for (int row = 0; row < M; ++row)
336  values[row * N + col] = T(m[col][row]);
337 }
338 
339 // Define aliases for the useful variants of QGenericMatrix.
348 
349 #ifndef QT_NO_DEBUG_STREAM
350 
351 template <int N, int M, typename T>
352 QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
353 {
354  dbg.nospace() << "QGenericMatrix<" << N << ", " << M
355  << ", " << QTypeInfo<T>::name()
356  << ">(" << endl << qSetFieldWidth(10);
357  for (int row = 0; row < M; ++row) {
358  for (int col = 0; col < N; ++col)
359  dbg << m(row, col);
360  dbg << endl;
361  }
362  dbg << qSetFieldWidth(0) << ')';
363  return dbg.space();
364 }
365 
366 #endif
367 
368 #ifndef QT_NO_DATASTREAM
369 
370 template <int N, int M, typename T>
371 QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
372 {
373  for (int row = 0; row < M; ++row)
374  for (int col = 0; col < N; ++col)
375  stream << double(matrix(row, col));
376  return stream;
377 }
378 
379 template <int N, int M, typename T>
381 {
382  double x;
383  for (int row = 0; row < M; ++row) {
384  for (int col = 0; col < N; ++col) {
385  stream >> x;
386  matrix(row, col) = T(x);
387  }
388  }
389  return stream;
390 }
391 
392 #endif
393 
395 
404 
406 
407 #endif
QGenericMatrix< N, M, T > & operator*=(T factor)
bool operator==(const QGenericMatrix< N, M, T > &other) const
GLuint GLenum matrix
Definition: GLee.h:6572
QGenericMatrix< 2, 4, qreal > QMatrix2x4
#define QT_END_NAMESPACE
Definition: qglobal.h:128
QByteArray & operator+=(QByteArray &a, const QStringBuilder< A, B > &b)
#define QT_BEGIN_HEADER
Definition: qglobal.h:141
QGenericMatrix< M, N, T > transposed() const
QGenericMatrix< 3, 4, qreal > QMatrix3x4
QGenericMatrix< 3, 3, qreal > QMatrix3x3
const T & operator()(int row, int column) const
void copyDataTo(T *values) const
const T * data() const
bool isIdentity() const
Q_OUTOFLINE_TEMPLATE QGenericMatrix< N, M, T > operator-(const QGenericMatrix< N, M, T > &m1, const QGenericMatrix< N, M, T > &m2)
Definition: qdebug.h:62
#define Q_DECLARE_METATYPE(TYPE)
Definition: qmetatype.h:265
QGenericMatrix< N, M, T > & operator+=(const QGenericMatrix< N, M, T > &other)
QDataStream & operator>>(QDataStream &stream, QGenericMatrix< N, M, T > &matrix)
QGenericMatrix< 2, 2, qreal > QMatrix2x2
bool operator==(const Attribute &cA, const AttributeInstance< type > &cB)
This operator compares the two attributes and NOT their values.
Definition: node.h:577
QGenericMatrix< 4, 3, qreal > QMatrix4x3
GLenum GLenum GLvoid * row
Definition: GLee.h:893
#define QT_BEGIN_NAMESPACE
Definition: qglobal.h:127
bool operator!=(const QGenericMatrix< N, M, T > &other) const
QGenericMatrix< 3, 2, qreal > QMatrix3x2
GLenum GLint x
Definition: GLee.h:876
Q_OUTOFLINE_TEMPLATE QGenericMatrix< N, M, T > operator/(const QGenericMatrix< N, M, T > &matrix, T divisor)
QDebug & nospace()
Definition: qdebug.h:92
bool operator!=(const QByteArray &a1, const QByteArray &a2)
Definition: qbytearray.h:533
GLsizei const GLfloat * value
Definition: GLee.h:1742
GLenum GLenum GLvoid GLvoid * column
Definition: GLee.h:893
GLuint const GLchar * name
Definition: GLee.h:1704
Q_OUTOFLINE_TEMPLATE QGenericMatrix< N, M, T > operator+(const QGenericMatrix< N, M, T > &m1, const QGenericMatrix< N, M, T > &m2)
void fill(T value)
QGenericMatrix< 2, 3, qreal > QMatrix2x3
QGenericMatrix< 4, 2, qreal > QMatrix4x2
GLboolean GLenum GLenum GLvoid * values
Definition: GLee.h:895
GLXDrawable int64_t int64_t divisor
Definition: GLee.h:10690
QTextStreamManipulator qSetFieldWidth(int width)
Definition: qtextstream.h:329
#define QT_END_HEADER
Definition: qglobal.h:142
GLclampf f
Definition: GLee.h:9303
QGenericMatrix< N, M, T > & operator/=(T divisor)
const T * constData() const
Q_OUTOFLINE_TEMPLATE QGenericMatrix< M1, M2, T > operator*(const QGenericMatrix< N, M2, T > &m1, const QGenericMatrix< M1, N, T > &m2)
QGenericMatrix< N, M, T > & operator-=(const QGenericMatrix< N, M, T > &other)
Q_CORE_EXPORT QTextStream & endl(QTextStream &s)