00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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];
00105
00106 QGenericMatrix(int) {}
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
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