src/matrix.h

changeset 17
a5111f4e6412
parent 11
771168ee2c76
child 21
0133e565e072
equal deleted inserted replaced
16:aeb5f203b3eb 17:a5111f4e6412
1 #pragma once 1 #pragma once
2 #include <QGenericMatrix> 2 #include <QGenericMatrix>
3 #include <type_traits>
4
5 template<int Rows, int Columns, typename T = double>
6 struct MatrixIterator;
7
8 template<int Rows, int Columns>
9 struct MatrixIndex
10 {
11 int row;
12 int column;
13 };
3 14
4 template<int Rows, int Columns, typename T = double> 15 template<int Rows, int Columns, typename T = double>
5 struct Matrix 16 struct Matrix
6 { 17 {
18 using Iterator = MatrixIterator<Rows, Columns, T>;
7 T values[Rows][Columns]; 19 T values[Rows][Columns];
20 Iterator begin()
21 {
22 return {*this, {0, 0}};
23 }
24 Iterator end()
25 {
26 return {*this, {Rows, 0}};
27 }
8 T& operator()(int row, int column) 28 T& operator()(int row, int column)
9 { 29 {
10 return this->values[row][column]; 30 return this->values[row][column];
11 } 31 }
12 T operator()(int row, int column) const 32 T operator()(int row, int column) const
13 { 33 {
14 return this->values[row][column]; 34 return this->values[row][column];
15 } 35 }
36 T& operator[](const MatrixIndex<Rows, Columns>& index)
37 {
38 return (*this)(index.row, index.column);
39 }
40 T operator[](const MatrixIndex<Rows, Columns>& index) const
41 {
42 return (*this)(index.row, index.column);
43 }
16 }; 44 };
45
46 template<int Rows, int Columns, typename T>
47 struct MatrixIterator
48 {
49 struct Value
50 {
51 const MatrixIndex<Rows, Columns> index;
52 decltype(std::declval<Matrix<Rows, Columns, T>>()(0, 0)) value;
53 };
54 Matrix<Rows, Columns, T>& matrix;
55 MatrixIndex<Rows, Columns> index;
56 };
57
58 template<int Rows, int Columns>
59 auto& operator++(MatrixIndex<Rows, Columns>& index)
60 {
61 index.column += 1;
62 if (index.column >= Columns)
63 {
64 index.row += 1;
65 index.column -= Columns;
66 }
67 return index;
68 }
69
70 template<int Rows, int Columns>
71 bool operator==(
72 const MatrixIndex<Rows, Columns>& one,
73 const MatrixIndex<Rows, Columns>& other)
74 {
75 return one.row == other.row and one.column == other.column;
76 }
77 template<int Rows, int Columns, typename T>
78 auto& operator++(MatrixIterator<Rows, Columns, T>& iterator)
79 {
80 ++iterator.index;
81 return iterator;
82 }
83
84 template<int Rows, int Columns, typename T>
85 bool operator==(
86 const MatrixIterator<Rows, Columns, T>& one,
87 const MatrixIterator<Rows, Columns, T>& other)
88 {
89 return &one.matrix == &other.matrix and one.index == other.index;
90 }
91
92 template<int Rows, int Columns, typename T>
93 bool operator!=(
94 const MatrixIterator<Rows, Columns, T>& one,
95 const MatrixIterator<Rows, Columns, T>& other)
96 {
97 return not (one == other);
98 }
99
100 template<int Rows, int Columns, typename T>
101 auto operator*(MatrixIterator<Rows, Columns, T>& iterator)
102 -> typename MatrixIterator<Rows, Columns, T>::Value
103 {
104 return {iterator.index, iterator.matrix[iterator.index]};
105 }
17 106
18 template<int Rows, int Columns, typename T> 107 template<int Rows, int Columns, typename T>
19 QGenericMatrix<Rows, Columns, T> matrixToQGenericMatrix(const Matrix<Rows, Columns, T>& matrix) 108 QGenericMatrix<Rows, Columns, T> matrixToQGenericMatrix(const Matrix<Rows, Columns, T>& matrix)
20 { 109 {
21 return {matrix.values}; 110 return {matrix.values};
23 112
24 template<int Rows, int Columns, typename T> 113 template<int Rows, int Columns, typename T>
25 Matrix<Rows, Columns, T> matrixFromQGenericMatrix(const QGenericMatrix<Rows, Columns, T&> matrix) 114 Matrix<Rows, Columns, T> matrixFromQGenericMatrix(const QGenericMatrix<Rows, Columns, T&> matrix)
26 { 115 {
27 Matrix<Rows, Columns, T> result; 116 Matrix<Rows, Columns, T> result;
28 for (int row = 0; row < Rows; row += 1) 117 for (auto& cell : result)
29 { 118 {
30 for (int column = 0; column < Columns; column += 1) 119 matrix(cell.index.row, cell.index.column) = result[cell.index];
31 {
32 result(row, column) = matrix(row, column);
33 }
34 } 120 }
35 return result; 121 return result;
36 } 122 }
37 123
38 using Matrix3x3 = Matrix<3, 3>; 124 using Matrix3x3 = Matrix<3, 3>;
41 Q_DECLARE_METATYPE(Matrix4x4); 127 Q_DECLARE_METATYPE(Matrix4x4);
42 128
43 template<int Rows, int Columns, typename T> 129 template<int Rows, int Columns, typename T>
44 QDataStream& operator<<(QDataStream& stream, const Matrix<Rows, Columns, T>& matrix) 130 QDataStream& operator<<(QDataStream& stream, const Matrix<Rows, Columns, T>& matrix)
45 { 131 {
46 return stream << matrixToQGenericMatrix(matrix); 132 for (auto& cell : matrix)
133 {
134 stream << cell.value;
135 }
136 return stream;
47 } 137 }
48 138
49 template<int Rows, int Columns, typename T> 139 template<int Rows, int Columns, typename T>
50 QDataStream& operator>>(QDataStream& stream, Matrix<Rows, Columns, T>& matrix) 140 QDataStream& operator>>(QDataStream& stream, Matrix<Rows, Columns, T>& matrix)
51 { 141 {
52 QGenericMatrix<Rows, Columns, T> qmatrix; 142 for (auto& cell : matrix)
53 stream >> qmatrix; 143 {
54 matrix = matrixFromQGenericMatrix(matrix); 144 stream >> cell.value;
145 }
55 return stream; 146 return stream;
56 } 147 }
148
149 static constexpr Matrix3x3 identity3x3 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}};
150 static constexpr Matrix4x4 identity4x4 {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};

mercurial