- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qgenericmatrix.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtGui module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    00039 **
    00040 ****************************************************************************/
    00041
    00042 #ifndef QGENERICMATRIX_H
    00043 #define QGENERICMATRIX_H
    00044
    00045 #include <QtCore/qmetatype.h>
    00046 #include <QtCore/qdebug.h>
    00047 #include <QtCore/qdatastream.h>
    00048
    00049 QT_BEGIN_HEADER
    00050
    00051 QT_BEGIN_NAMESPACE
    00052
    00053 QT_MODULE(Gui)
    00054
    00055 template <int N, int M, typename T>
    00056 class QGenericMatrix
    00057 {
    00058 public:
    00059     QGenericMatrix();
    00060     QGenericMatrix(const QGenericMatrix<N, M, T>& other);
    00061     explicit QGenericMatrix(const T *values);
    00062
    00063     const T& operator()(int row, int column) const;
    00064     T& operator()(int row, int column);
    00065
    00066     bool isIdentity() const;
    00067     void setToIdentity();
    00068
    00069     void fill(T value);
    00070
    00071     QGenericMatrix<M, N, T> transposed() const;
    00072
    00073     QGenericMatrix<N, M, T>& operator+=(const QGenericMatrix<N, M, T>& other);
    00074     QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other);
    00075     QGenericMatrix<N, M, T>& operator*=(T factor);
    00076     QGenericMatrix<N, M, T>& operator/=(T divisor);
    00077     bool operator==(const QGenericMatrix<N, M, T>& other) const;
    00078     bool operator!=(const QGenericMatrix<N, M, T>& other) const;
    00079
    00080     void copyDataTo(T *values) const;
    00081
    00082     T *data() { return m[0]; }
    00083     const T *data() const { return m[0]; }
    00084     const T *constData() const { return m[0]; }
    00085
    00086 #if !defined(Q_NO_TEMPLATE_FRIENDS)
    00087     template<int NN, int MM, typename TT>
    00088     friend QGenericMatrix<NN, MM, TT> operator+(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
    00089     template<int NN, int MM, typename TT>
    00090     friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
    00091     template<int NN, int M1, int M2, typename TT>
    00092     friend QGenericMatrix<M1, M2, TT> operator*(const QGenericMatrix<NN, M2, TT>& m1, const QGenericMatrix<M1, NN, TT>& m2);
    00093     template<int NN, int MM, typename TT>
    00094     friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& matrix);
    00095     template<int NN, int MM, typename TT>
    00096     friend QGenericMatrix<NN, MM, TT> operator*(TT factor, const QGenericMatrix<NN, MM, TT>& matrix);
    00097     template<int NN, int MM, typename TT>
    00098     friend QGenericMatrix<NN, MM, TT> operator*(const QGenericMatrix<NN, MM, TT>& matrix, TT factor);
    00099     template<int NN, int MM, typename TT>
    00100     friend QGenericMatrix<NN, MM, TT> operator/(const QGenericMatrix<NN, MM, TT>& matrix, TT divisor);
    00101
    00102 private:
    00103 #endif
    00104     T m[N][M];    // Column-major order to match OpenGL.
    00105
    00106     QGenericMatrix(int) {}       // Construct without initializing identity matrix.
    00107
    00108 #if !defined(Q_NO_TEMPLATE_FRIENDS)
    00109     template <int NN, int MM, typename TT>
    00110     friend class QGenericMatrix;
    00111 #endif
    00112 };
    00113
    00114 template <int N, int M, typename T>
    00115 Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
    00116 {
    00117     setToIdentity();
    00118 }
    00119
    00120 template <int N, int M, typename T>
    00121 Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const QGenericMatrix<N, M, T>& other)
    00122 {
    00123     for (int col = 0; col < N; ++col)
    00124         for (int row = 0; row < M; ++row)
    00125             m[col][row] = other.m[col][row];
    00126 }
    00127
    00128 template <int N, int M, typename T>
    00129 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values)
    00130 {
    00131     for (int col = 0; col < N; ++col)
    00132         for (int row = 0; row < M; ++row)
    00133             m[col][row] = values[row * N + col];
    00134 }
    00135
    00136 template <int N, int M, typename T>
    00137 Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const
    00138 {
    00139     Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
    00140     return m[column][row];
    00141 }
    00142
    00143 template <int N, int M, typename T>
    00144 Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column)
    00145 {
    00146     Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
    00147     return m[column][row];
    00148 }
    00149
    00150 template <int N, int M, typename T>
    00151 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
    00152 {
    00153     for (int col = 0; col < N; ++col) {
    00154         for (int row = 0; row < M; ++row) {
    00155             if (row == col) {
    00156                 if (m[col][row] != 1.0f)
    00157                     return false;
    00158             } else {
    00159                 if (m[col][row] != 0.0f)
    00160                     return false;
    00161             }
    00162         }
    00163     }
    00164     return true;
    00165 }
    00166
    00167 template <int N, int M, typename T>
    00168 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
    00169 {
    00170     for (int col = 0; col < N; ++col) {
    00171         for (int row = 0; row < M; ++row) {
    00172             if (row == col)
    00173                 m[col][row] = 1.0f;
    00174             else
    00175                 m[col][row] = 0.0f;
    00176         }
    00177     }
    00178 }
    00179
    00180 template <int N, int M, typename T>
    00181 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value)
    00182 {
    00183     for (int col = 0; col < N; ++col)
    00184         for (int row = 0; row < M; ++row)
    00185             m[col][row] = value;
    00186 }
    00187
    00188 template <int N, int M, typename T>
    00189 Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T> QGenericMatrix<N, M, T>::transposed() const
    00190 {
    00191     QGenericMatrix<M, N, T> result(1);
    00192     for (int row = 0; row < M; ++row)
    00193         for (int col = 0; col < N; ++col)
    00194             result.m[row][col] = m[col][row];
    00195     return result;
    00196 }
    00197
    00198 template <int N, int M, typename T>
    00199 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator+=(const QGenericMatrix<N, M, T>& other)
    00200 {
    00201     for (int index = 0; index < N * M; ++index)
    00202         m[0][index] += other.m[0][index];
    00203     return *this;
    00204 }
    00205
    00206 template <int N, int M, typename T>
    00207 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other)
    00208 {
    00209     for (int index = 0; index < N * M; ++index)
    00210         m[0][index] -= other.m[0][index];
    00211     return *this;
    00212 }
    00213
    00214 template <int N, int M, typename T>
    00215 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor)
    00216 {
    00217     for (int index = 0; index < N * M; ++index)
    00218         m[0][index] *= factor;
    00219     return *this;
    00220 }
    00221
    00222 template <int N, int M, typename T>
    00223 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
    00224 {
    00225     for (int index = 0; index < N * M; ++index) {
    00226         if (m[0][index] != other.m[0][index])
    00227             return false;
    00228     }
    00229     return true;
    00230 }
    00231
    00232 template <int N, int M, typename T>
    00233 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
    00234 {
    00235     for (int index = 0; index < N * M; ++index) {
    00236         if (m[0][index] != other.m[0][index])
    00237             return true;
    00238     }
    00239     return false;
    00240 }
    00241
    00242 template <int N, int M, typename T>
    00243 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor)
    00244 {
    00245     for (int index = 0; index < N * M; ++index)
    00246         m[0][index] /= divisor;
    00247     return *this;
    00248 }
    00249
    00250 template <int N, int M, typename T>
    00251 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
    00252 {
    00253     QGenericMatrix<N, M, T> result(1);
    00254     for (int index = 0; index < N * M; ++index)
    00255         result.m[0][index] = m1.m[0][index] + m2.m[0][index];
    00256     return result;
    00257 }
    00258
    00259 template <int N, int M, typename T>
    00260 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
    00261 {
    00262     QGenericMatrix<N, M, T> result(1);
    00263     for (int index = 0; index < N * M; ++index)
    00264         result.m[0][index] = m1.m[0][index] - m2.m[0][index];
    00265     return result;
    00266 }
    00267
    00268 template <int N, int M1, int M2, typename T>
    00269 Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2)
    00270 {
    00271     QGenericMatrix<M1, M2, T> result(1);
    00272     for (int row = 0; row < M2; ++row) {
    00273         for (int col = 0; col < M1; ++col) {
    00274             T sum(0.0f);
    00275             for (int j = 0; j < N; ++j)
    00276                 sum += m1.m[j][row] * m2.m[col][j];
    00277             result.m[col][row] = sum;
    00278         }
    00279     }
    00280     return result;
    00281 }
    00282
    00283 template <int N, int M, typename T>
    00284 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix)
    00285 {
    00286     QGenericMatrix<N, M, T> result(1);
    00287     for (int index = 0; index < N * M; ++index)
    00288         result.m[0][index] = -matrix.m[0][index];
    00289     return result;
    00290 }
    00291
    00292 template <int N, int M, typename T>
    00293 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
    00294 {
    00295     QGenericMatrix<N, M, T> result(1);
    00296     for (int index = 0; index < N * M; ++index)
    00297         result.m[0][index] = matrix.m[0][index] * factor;
    00298     return result;
    00299 }
    00300
    00301 template <int N, int M, typename T>
    00302 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
    00303 {
    00304     QGenericMatrix<N, M, T> result(1);
    00305     for (int index = 0; index < N * M; ++index)
    00306         result.m[0][index] = matrix.m[0][index] * factor;
    00307     return result;
    00308 }
    00309
    00310 template <int N, int M, typename T>
    00311 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor)
    00312 {
    00313     QGenericMatrix<N, M, T> result(1);
    00314     for (int index = 0; index < N * M; ++index)
    00315         result.m[0][index] = matrix.m[0][index] / divisor;
    00316     return result;
    00317 }
    00318
    00319 template <int N, int M, typename T>
    00320 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
    00321 {
    00322     for (int col = 0; col < N; ++col)
    00323         for (int row = 0; row < M; ++row)
    00324             values[row * N + col] = T(m[col][row]);
    00325 }
    00326
    00327 // Define aliases for the useful variants of QGenericMatrix.
    00328 typedef QGenericMatrix<2, 2, qreal> QMatrix2x2;
    00329 typedef QGenericMatrix<2, 3, qreal> QMatrix2x3;
    00330 typedef QGenericMatrix<2, 4, qreal> QMatrix2x4;
    00331 typedef QGenericMatrix<3, 2, qreal> QMatrix3x2;
    00332 typedef QGenericMatrix<3, 3, qreal> QMatrix3x3;
    00333 typedef QGenericMatrix<3, 4, qreal> QMatrix3x4;
    00334 typedef QGenericMatrix<4, 2, qreal> QMatrix4x2;
    00335 typedef QGenericMatrix<4, 3, qreal> QMatrix4x3;
    00336
    00337 #ifndef QT_NO_DEBUG_STREAM
    00338
    00339 template <int N, int M, typename T>
    00340 QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
    00341 {
    00342     dbg.nospace() << "QGenericMatrix<" << N << ", " << M
    00343         << ", " << QTypeInfo<T>::name()
    00344         << ">(" << endl << qSetFieldWidth(10);
    00345     for (int row = 0; row < M; ++row) {
    00346         for (int col = 0; col < N; ++col)
    00347             dbg << m(row, col);
    00348         dbg << endl;
    00349     }
    00350     dbg << qSetFieldWidth(0) << ')';
    00351     return dbg.space();
    00352 }
    00353
    00354 #endif
    00355
    00356 #ifndef QT_NO_DATASTREAM
    00357
    00358 template <int N, int M, typename T>
    00359 QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
    00360 {
    00361     for (int row = 0; row < M; ++row)
    00362         for (int col = 0; col < N; ++col)
    00363             stream << double(matrix(row, col));
    00364     return stream;
    00365 }
    00366
    00367 template <int N, int M, typename T>
    00368 QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
    00369 {
    00370     double x;
    00371     for (int row = 0; row < M; ++row) {
    00372         for (int col = 0; col < N; ++col) {
    00373             stream >> x;
    00374             matrix(row, col) = T(x);
    00375         }
    00376     }
    00377     return stream;
    00378 }
    00379
    00380 #endif
    00381
    00382 QT_END_NAMESPACE
    00383
    00384 Q_DECLARE_METATYPE(QMatrix2x2)
    00385 Q_DECLARE_METATYPE(QMatrix2x3)
    00386 Q_DECLARE_METATYPE(QMatrix2x4)
    00387 Q_DECLARE_METATYPE(QMatrix3x2)
    00388 Q_DECLARE_METATYPE(QMatrix3x3)
    00389 Q_DECLARE_METATYPE(QMatrix3x4)
    00390 Q_DECLARE_METATYPE(QMatrix4x2)
    00391 Q_DECLARE_METATYPE(QMatrix4x3)
    00392
    00393 QT_END_HEADER
    00394
    00395 #endif