File indexing completed on 2025-01-18 10:07:59
0001
0002
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];
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
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