Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:59

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 
0004 #ifndef QGENERICMATRIX_H
0005 #define QGENERICMATRIX_H
0006 
0007 #include <QtGui/qtguiglobal.h>
0008 #include <QtCore/qmetatype.h>
0009 #include <QtCore/qdebug.h>
0010 #include <QtCore/qdatastream.h>
0011 
0012 QT_BEGIN_NAMESPACE
0013 
0014 
0015 template <int N, int M, typename T>
0016 class QGenericMatrix
0017 {
0018 public:
0019     QGenericMatrix();
0020     explicit QGenericMatrix(Qt::Initialization) {}
0021     explicit QGenericMatrix(const T *values);
0022 
0023     const T& operator()(int row, int column) const;
0024     T& operator()(int row, int column);
0025 
0026     bool isIdentity() const;
0027     void setToIdentity();
0028 
0029     void fill(T value);
0030 
0031     [[nodiscard]] QGenericMatrix<M, N, T> transposed() const;
0032 
0033     QGenericMatrix<N, M, T>& operator+=(const QGenericMatrix<N, M, T>& other);
0034     QGenericMatrix<N, M, T>& operator-=(const QGenericMatrix<N, M, T>& other);
0035     QGenericMatrix<N, M, T>& operator*=(T factor);
0036     QGenericMatrix<N, M, T>& operator/=(T divisor);
0037     bool operator==(const QGenericMatrix<N, M, T>& other) const;
0038     bool operator!=(const QGenericMatrix<N, M, T>& other) const;
0039 
0040     void copyDataTo(T *values) const;
0041 
0042     T *data() { return *m; }
0043     const T *data() const { return *m; }
0044     const T *constData() const { return *m; }
0045 
0046     template<int NN, int MM, typename TT>
0047     friend QGenericMatrix<NN, MM, TT> operator+(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
0048     template<int NN, int MM, typename TT>
0049     friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& m1, const QGenericMatrix<NN, MM, TT>& m2);
0050     template<int NN, int M1, int M2, typename TT>
0051     friend QGenericMatrix<M1, M2, TT> operator*(const QGenericMatrix<NN, M2, TT>& m1, const QGenericMatrix<M1, NN, TT>& m2);
0052     template<int NN, int MM, typename TT>
0053     friend QGenericMatrix<NN, MM, TT> operator-(const QGenericMatrix<NN, MM, TT>& matrix);
0054     template<int NN, int MM, typename TT>
0055     friend QGenericMatrix<NN, MM, TT> operator*(TT factor, const QGenericMatrix<NN, MM, TT>& matrix);
0056     template<int NN, int MM, typename TT>
0057     friend QGenericMatrix<NN, MM, TT> operator*(const QGenericMatrix<NN, MM, TT>& matrix, TT factor);
0058     template<int NN, int MM, typename TT>
0059     friend QGenericMatrix<NN, MM, TT> operator/(const QGenericMatrix<NN, MM, TT>& matrix, TT divisor);
0060 
0061 private:
0062     T m[N][M];    // Column-major order to match OpenGL.
0063 
0064     template <int NN, int MM, typename TT>
0065     friend class QGenericMatrix;
0066 };
0067 template <int N, int M, typename T>
0068 class QTypeInfo<QGenericMatrix<N, M, T> >
0069     : public QTypeInfoMerger<QGenericMatrix<N, M, T>, T>
0070 {
0071 };
0072 
0073 template <int N, int M, typename T>
0074 Q_INLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix()
0075 {
0076     setToIdentity();
0077 }
0078 
0079 template <int N, int M, typename T>
0080 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>::QGenericMatrix(const T *values)
0081 {
0082     for (int col = 0; col < N; ++col)
0083         for (int row = 0; row < M; ++row)
0084             m[col][row] = values[row * N + col];
0085 }
0086 
0087 template <int N, int M, typename T>
0088 Q_INLINE_TEMPLATE const T& QGenericMatrix<N, M, T>::operator()(int row, int column) const
0089 {
0090     Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
0091     return m[column][row];
0092 }
0093 
0094 template <int N, int M, typename T>
0095 Q_INLINE_TEMPLATE T& QGenericMatrix<N, M, T>::operator()(int row, int column)
0096 {
0097     Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N);
0098     return m[column][row];
0099 }
0100 
0101 template <int N, int M, typename T>
0102 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::isIdentity() const
0103 {
0104     for (int col = 0; col < N; ++col) {
0105         for (int row = 0; row < M; ++row) {
0106             if (row == col) {
0107                 if (m[col][row] != 1.0f)
0108                     return false;
0109             } else {
0110                 if (m[col][row] != 0.0f)
0111                     return false;
0112             }
0113         }
0114     }
0115     return true;
0116 }
0117 
0118 template <int N, int M, typename T>
0119 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::setToIdentity()
0120 {
0121     for (int col = 0; col < N; ++col) {
0122         for (int row = 0; row < M; ++row) {
0123             if (row == col)
0124                 m[col][row] = 1.0f;
0125             else
0126                 m[col][row] = 0.0f;
0127         }
0128     }
0129 }
0130 
0131 template <int N, int M, typename T>
0132 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::fill(T value)
0133 {
0134     for (int col = 0; col < N; ++col)
0135         for (int row = 0; row < M; ++row)
0136             m[col][row] = value;
0137 }
0138 
0139 template <int N, int M, typename T>
0140 Q_OUTOFLINE_TEMPLATE QGenericMatrix<M, N, T> QGenericMatrix<N, M, T>::transposed() const
0141 {
0142     QGenericMatrix<M, N, T> result(Qt::Uninitialized);
0143     for (int row = 0; row < M; ++row)
0144         for (int col = 0; col < N; ++col)
0145             result.m[row][col] = m[col][row];
0146     return result;
0147 }
0148 
0149 template <int N, int M, typename T>
0150 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator+=(const QGenericMatrix<N, M, T>& other)
0151 {
0152     for (int row = 0; row < M; ++row)
0153         for (int col = 0; col < N; ++col)
0154             m[col][row] += other.m[col][row];
0155     return *this;
0156 }
0157 
0158 template <int N, int M, typename T>
0159 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator-=(const QGenericMatrix<N, M, T>& other)
0160 {
0161     for (int row = 0; row < M; ++row)
0162         for (int col = 0; col < N; ++col)
0163             m[col][row] -= other.m[col][row];
0164     return *this;
0165 }
0166 
0167 template <int N, int M, typename T>
0168 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator*=(T factor)
0169 {
0170     for (int row = 0; row < M; ++row)
0171         for (int col = 0; col < N; ++col)
0172             m[col][row] *= factor;
0173     return *this;
0174 }
0175 
0176 QT_WARNING_PUSH
0177 QT_WARNING_DISABLE_FLOAT_COMPARE
0178 
0179 template <int N, int M, typename T>
0180 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator==(const QGenericMatrix<N, M, T>& other) const
0181 {
0182     for (int row = 0; row < M; ++row)
0183         for (int col = 0; col < N; ++col)  {
0184             if (m[col][row] != other.m[col][row])
0185                 return false;
0186         }
0187     return true;
0188 }
0189 
0190 template <int N, int M, typename T>
0191 Q_OUTOFLINE_TEMPLATE bool QGenericMatrix<N, M, T>::operator!=(const QGenericMatrix<N, M, T>& other) const
0192 {
0193     return !(*this == other);
0194 }
0195 
0196 QT_WARNING_POP
0197 
0198 template <int N, int M, typename T>
0199 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T>& QGenericMatrix<N, M, T>::operator/=(T divisor)
0200 {
0201     for (int row = 0; row < M; ++row)
0202         for (int col = 0; col < N; ++col)
0203             m[col][row] /= divisor;
0204     return *this;
0205 }
0206 
0207 template <int N, int M, typename T>
0208 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator+(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
0209 {
0210     QGenericMatrix<N, M, T> result(Qt::Uninitialized);
0211     for (int row = 0; row < M; ++row)
0212         for (int col = 0; col < N; ++col)
0213             result.m[col][row] = m1.m[col][row] + m2.m[col][row];
0214     return result;
0215 }
0216 
0217 template <int N, int M, typename T>
0218 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& m1, const QGenericMatrix<N, M, T>& m2)
0219 {
0220     QGenericMatrix<N, M, T> result(Qt::Uninitialized);
0221     for (int row = 0; row < M; ++row)
0222         for (int col = 0; col < N; ++col)
0223             result.m[col][row] = m1.m[col][row] - m2.m[col][row];
0224     return result;
0225 }
0226 
0227 template <int N, int M1, int M2, typename T>
0228 Q_OUTOFLINE_TEMPLATE QGenericMatrix<M1, M2, T> operator*(const QGenericMatrix<N, M2, T>& m1, const QGenericMatrix<M1, N, T>& m2)
0229 {
0230     QGenericMatrix<M1, M2, T> result(Qt::Uninitialized);
0231     for (int row = 0; row < M2; ++row) {
0232         for (int col = 0; col < M1; ++col) {
0233             T sum(0.0f);
0234             for (int j = 0; j < N; ++j)
0235                 sum += m1.m[j][row] * m2.m[col][j];
0236             result.m[col][row] = sum;
0237         }
0238     }
0239     return result;
0240 }
0241 
0242 template <int N, int M, typename T>
0243 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator-(const QGenericMatrix<N, M, T>& matrix)
0244 {
0245     QGenericMatrix<N, M, T> result(Qt::Uninitialized);
0246     for (int row = 0; row < M; ++row)
0247         for (int col = 0; col < N; ++col)
0248             result.m[col][row] = -matrix.m[col][row];
0249     return result;
0250 }
0251 
0252 template <int N, int M, typename T>
0253 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(T factor, const QGenericMatrix<N, M, T>& matrix)
0254 {
0255     QGenericMatrix<N, M, T> result(Qt::Uninitialized);
0256     for (int row = 0; row < M; ++row)
0257         for (int col = 0; col < N; ++col)
0258             result.m[col][row] = matrix.m[col][row] * factor;
0259     return result;
0260 }
0261 
0262 template <int N, int M, typename T>
0263 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator*(const QGenericMatrix<N, M, T>& matrix, T factor)
0264 {
0265     QGenericMatrix<N, M, T> result(Qt::Uninitialized);
0266     for (int row = 0; row < M; ++row)
0267         for (int col = 0; col < N; ++col)
0268             result.m[col][row] = matrix.m[col][row] * factor;
0269     return result;
0270 }
0271 
0272 template <int N, int M, typename T>
0273 Q_OUTOFLINE_TEMPLATE QGenericMatrix<N, M, T> operator/(const QGenericMatrix<N, M, T>& matrix, T divisor)
0274 {
0275     QGenericMatrix<N, M, T> result(Qt::Uninitialized);
0276     for (int row = 0; row < M; ++row)
0277         for (int col = 0; col < N; ++col)
0278             result.m[col][row] = matrix.m[col][row] / divisor;
0279     return result;
0280 }
0281 
0282 template <int N, int M, typename T>
0283 Q_OUTOFLINE_TEMPLATE void QGenericMatrix<N, M, T>::copyDataTo(T *values) const
0284 {
0285     for (int col = 0; col < N; ++col)
0286         for (int row = 0; row < M; ++row)
0287             values[row * N + col] = T(m[col][row]);
0288 }
0289 
0290 // Define aliases for the useful variants of QGenericMatrix.
0291 typedef QGenericMatrix<2, 2, float> QMatrix2x2;
0292 typedef QGenericMatrix<2, 3, float> QMatrix2x3;
0293 typedef QGenericMatrix<2, 4, float> QMatrix2x4;
0294 typedef QGenericMatrix<3, 2, float> QMatrix3x2;
0295 typedef QGenericMatrix<3, 3, float> QMatrix3x3;
0296 typedef QGenericMatrix<3, 4, float> QMatrix3x4;
0297 typedef QGenericMatrix<4, 2, float> QMatrix4x2;
0298 typedef QGenericMatrix<4, 3, float> QMatrix4x3;
0299 
0300 #ifndef QT_NO_DEBUG_STREAM
0301 
0302 template <int N, int M, typename T>
0303 QDebug operator<<(QDebug dbg, const QGenericMatrix<N, M, T> &m)
0304 {
0305     QDebugStateSaver saver(dbg);
0306     dbg.nospace() << "QGenericMatrix<" << N << ", " << M
0307         << ", " << QMetaType::fromType<T>().name()
0308         << ">(" << Qt::endl << qSetFieldWidth(10);
0309     for (int row = 0; row < M; ++row) {
0310         for (int col = 0; col < N; ++col)
0311             dbg << m(row, col);
0312         dbg << Qt::endl;
0313     }
0314     dbg << qSetFieldWidth(0) << ')';
0315     return dbg;
0316 }
0317 
0318 #endif
0319 
0320 #ifndef QT_NO_DATASTREAM
0321 
0322 template <int N, int M, typename T>
0323 QDataStream &operator<<(QDataStream &stream, const QGenericMatrix<N, M, T> &matrix)
0324 {
0325     for (int row = 0; row < M; ++row)
0326         for (int col = 0; col < N; ++col)
0327             stream << double(matrix(row, col));
0328     return stream;
0329 }
0330 
0331 template <int N, int M, typename T>
0332 QDataStream &operator>>(QDataStream &stream, QGenericMatrix<N, M, T> &matrix)
0333 {
0334     double x;
0335     for (int row = 0; row < M; ++row) {
0336         for (int col = 0; col < N; ++col) {
0337             stream >> x;
0338             matrix(row, col) = T(x);
0339         }
0340     }
0341     return stream;
0342 }
0343 
0344 #endif
0345 
0346 QT_END_NAMESPACE
0347 
0348 QT_DECL_METATYPE_EXTERN(QMatrix2x2, Q_GUI_EXPORT)
0349 QT_DECL_METATYPE_EXTERN(QMatrix2x3, Q_GUI_EXPORT)
0350 QT_DECL_METATYPE_EXTERN(QMatrix2x4, Q_GUI_EXPORT)
0351 QT_DECL_METATYPE_EXTERN(QMatrix3x2, Q_GUI_EXPORT)
0352 QT_DECL_METATYPE_EXTERN(QMatrix3x3, Q_GUI_EXPORT)
0353 QT_DECL_METATYPE_EXTERN(QMatrix3x4, Q_GUI_EXPORT)
0354 QT_DECL_METATYPE_EXTERN(QMatrix4x2, Q_GUI_EXPORT)
0355 QT_DECL_METATYPE_EXTERN(QMatrix4x3, Q_GUI_EXPORT)
0356 
0357 #endif