Otclient  14/8/2020
matrix.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifndef MATRIX_H
24 #define MATRIX_H
25 
26 #include <array>
27 #include <cstring>
28 #include <initializer_list>
29 #include <sstream>
30 
31 template<int N, int M, typename T = float>
32 class Matrix
33 {
34 public:
36  Matrix(int) {} // construct without initializing identity matrix
37  Matrix(const Matrix<N,M,T>& other) = default;
38  template<typename U>
39  Matrix(const std::initializer_list<U>& values) { *this = values; }
40  template<typename U>
41  Matrix(const U *values) { *this = values; }
42 
43  void setIdentity();
44  bool isIdentity() const;
45  void fill(T value);
46 
47  Matrix<M,N,T> transposed() const;
48  typename std::enable_if<N==M>::type transpose() { *this = transposed(); }
49 
50  T *data() { return m[0]; }
51  const T *data() const { return m[0]; }
52 
53  T& operator()(int row, int column) { return m[row-1][column-1]; }
54  T operator()(int row, int column) const { return m[row-1][column-1]; }
55 
56  Matrix<N,M,T>& operator=(const Matrix<N,M,T>& other) = default;
57  template<typename U>
58  Matrix<N,M,T>& operator=(const std::initializer_list<U>& values);
59  template<typename U>
60  Matrix<N,M,T>& operator=(const U *values);
61  Matrix<N,M,T>& operator+=(const Matrix<N,M,T>& other);
62  Matrix<N,M,T>& operator-=(const Matrix<N,M,T>& other);
63  Matrix<N,M,T>& operator*=(T factor);
64  Matrix<N,M,T>& operator/=(T divisor);
65  bool operator==(const Matrix<N,M,T>& other) const;
66  bool operator!=(const Matrix<N,M,T>& other) const;
67 
68 private:
69  T m[N][M];
70 };
71 
72 template<int N, int M, typename T>
74  for(int i=0;i<N;++i) {
75  for(int j=0;j<M;++j) {
76  if(i==j)
77  m[i][j] = 1.0f;
78  else
79  m[i][j] = 0.0f;
80  }
81  }
82 }
83 
84 template<int N, int M, typename T>
86  for(int i=0;i<N;++i)
87  for(int j=0;j<M;++j)
88  if((i==j && m[i][j] != 1.0f) || (i!=j && m[i][j] != 0.0f))
89  return false;
90  return true;
91 }
92 
93 template<int N, int M, typename T>
94 void Matrix<N,M,T>::fill(T value) {
95  for(int i=0;i<N;++i)
96  for(int j=0;j<M;++j)
97  m[i][j] = value;
98 }
99 
100 template<int N, int M, typename T>
102  Matrix<M,N,T> result(1);
103  for(int i=0;i<N;++i)
104  for(int j=0;j<M;++j)
105  result.m[j][i] = m[i][j];
106  return result;
107 }
108 
109 template<int N, int M, typename T>
110 template<typename U>
111 Matrix<N,M,T>& Matrix<N,M,T>::operator=(const std::initializer_list<U>& values) {
112  auto it = values.begin();
113  for(int i=0;i<N;++i)
114  for(int j=0;j<M;++j)
115  m[i][j] = *(it++);
116  return *this;
117 }
118 
119 template<int N, int M, typename T>
120 template<typename U>
122  for(int i=0;i<N;++i)
123  for(int j=0;j<M;++j)
124  m[i][j] = values[i*N + j];
125  return *this;
126 }
127 
128 template<int N, int M, typename T>
130  for(int i=0;i<N;++i)
131  for(int j=0;j<M;++j)
132  m[i][j] += other.m[i][j];
133  return *this;
134 }
135 
136 template<int N, int M, typename T>
138  for(int i=0;i<N;++i)
139  for(int j=0;j<M;++j)
140  m[i][j] -= other.m[i][j];
141  return *this;
142 }
143 
144 template<int N, int M, typename T>
146  for(int i=0;i<N;++i)
147  for(int j=0;j<M;++j)
148  m[i][j] *= factor;
149  return *this;
150 }
151 
152 template<int N, int M, typename T>
154  for(int i=0;i<N;++i)
155  for(int j=0;j<M;++j)
156  m[i][j] /= divisor;
157  return *this;
158 }
159 
160 template<int N, int M, typename T>
161 bool Matrix<N,M,T>::operator==(const Matrix<N,M,T>& other) const
162 {
163  for(int i=0;i<N;++i)
164  for(int j=0;j<M;++j)
165  if(m[i][j] != other.m[i][j])
166  return false;
167  return true;
168 }
169 
170 template<int N, int M, typename T>
171 bool Matrix<N,M,T>::operator!=(const Matrix<N,M,T>& other) const
172 {
173  return !(*this == other);
174 }
175 
176 template<int N, int M, typename T>
177 std::ostream& operator<<(std::ostream& out, const Matrix<N,M,T>& mat)
178 {
179  for(int i=1;i<=N;++i) {
180  for(int j=1;j<=M;++j) {
181  out << mat(i,j);
182  if(j != M)
183  out << " ";
184  }
185  out << "\n";
186  }
187  return out;
188 }
189 
190 template<int N, int M, typename T>
191 std::istream& operator>>(std::istream& in, Matrix<N,M,T>& mat)
192 {
193  for(int i=0;i<N;++i)
194  for(int j=0;j<M;++j)
195  in >> mat(i,j);
196  return in;
197 }
198 
199 // faster comparing for 3x3 matrixes
200 template<>
201 inline bool Matrix<3,3,float>::operator==(const Matrix<3,3,float>& other) const
202 {
203  return m[0][0] == other.m[0][0] && m[1][1] == other.m[1][1] &&
204  m[2][1] == other.m[2][1] && m[2][0] == other.m[2][0] &&
205  m[1][2] == other.m[1][2] && m[0][2] == other.m[0][2] &&
206  m[1][0] == other.m[1][0] && m[0][1] == other.m[0][1] &&
207  m[2][2] == other.m[2][2];
208 }
209 
210 template<int M, int N, int P, int Q, typename T>
212 {
213  static_assert(N==P, "N==P");
214  Matrix<M,Q,T> c(1);
215  for(int i=1;i<=M;++i) {
216  for(int j=1;j<=Q;++j) {
217  T sum = 0;
218  for(int k=1;k<=N;++k)
219  sum += a(i,k) * b(k,j);
220  c(i,j) = sum;
221  }
222  }
223  return c;
224 }
225 
226 template<int M, int N, typename T>
227 Matrix<M, N, T> operator+(const Matrix<M,N,T>& a, const Matrix<M,N,T>& b) { Matrix<M,N,T> c(a); c += b; return c; }
228 
229 template<int M, int N, typename T>
230 Matrix<M, N, T> operator-(const Matrix<M,N,T>& a, const Matrix<M,N,T>& b) { Matrix<M,N,T> c(a); c -= b; return c; }
231 
232 template<int M, int N, typename T>
233 Matrix<M, N, T> operator*(const Matrix<M,N,T>& a, float b) { Matrix<M,N,T> c(a); c *= b; return c; }
234 
235 template<int M, int N, typename T>
236 Matrix<M, N, T> operator/(const Matrix<M,N,T>& a, float b) { Matrix<M,N,T> c = a; c /= b; return c; }
237 
241 
245 
246 #endif
Matrix::operator==
bool operator==(const Matrix< N, M, T > &other) const
Definition: matrix.h:161
operator/
Matrix< M, N, T > operator/(const Matrix< M, N, T > &a, float b)
Definition: matrix.h:236
Matrix::Matrix
Matrix(const U *values)
Definition: matrix.h:41
operator*
Matrix< M, Q, T > operator*(const Matrix< M, N, T > &a, const Matrix< P, Q, T > &b)
Definition: matrix.h:211
Matrix::transpose
std::enable_if< N==M >::type transpose()
Definition: matrix.h:48
Matrix::setIdentity
void setIdentity()
Definition: matrix.h:73
Matrix::operator+=
Matrix< N, M, T > & operator+=(const Matrix< N, M, T > &other)
Definition: matrix.h:129
Matrix::isIdentity
bool isIdentity() const
Definition: matrix.h:85
Matrix2x2
Matrix< 2, 2 > Matrix2x2
Definition: matrix.h:240
Matrix::Matrix
Matrix(int)
Definition: matrix.h:36
operator+
Matrix< M, N, T > operator+(const Matrix< M, N, T > &a, const Matrix< M, N, T > &b)
Definition: matrix.h:227
Matrix::operator()
T & operator()(int row, int column)
Definition: matrix.h:53
Matrix::operator*=
Matrix< N, M, T > & operator*=(T factor)
Definition: matrix.h:145
Matrix::data
const T * data() const
Definition: matrix.h:51
Matrix::transposed
Matrix< M, N, T > transposed() const
Definition: matrix.h:101
Matrix4x4
Matrix< 4, 4 > Matrix4x4
Definition: matrix.h:238
Matrix4
Matrix4x4 Matrix4
Definition: matrix.h:242
Matrix3
Matrix3x3 Matrix3
Definition: matrix.h:243
Matrix3x3
Matrix< 3, 3 > Matrix3x3
Definition: matrix.h:239
Matrix::operator=
Matrix< N, M, T > & operator=(const Matrix< N, M, T > &other)=default
operator>>
std::istream & operator>>(std::istream &in, Matrix< N, M, T > &mat)
Definition: matrix.h:191
Matrix::operator()
T operator()(int row, int column) const
Definition: matrix.h:54
Matrix::operator/=
Matrix< N, M, T > & operator/=(T divisor)
Definition: matrix.h:153
operator<<
std::ostream & operator<<(std::ostream &out, const Matrix< N, M, T > &mat)
Definition: matrix.h:177
Matrix2
Matrix2x2 Matrix2
Definition: matrix.h:244
Matrix::Matrix
Matrix(const std::initializer_list< U > &values)
Definition: matrix.h:39
Matrix
Definition: matrix.h:32
operator-
Matrix< M, N, T > operator-(const Matrix< M, N, T > &a, const Matrix< M, N, T > &b)
Definition: matrix.h:230
Matrix::operator-=
Matrix< N, M, T > & operator-=(const Matrix< N, M, T > &other)
Definition: matrix.h:137
Matrix::fill
void fill(T value)
Definition: matrix.h:94
Matrix::data
T * data()
Definition: matrix.h:50
Matrix::operator!=
bool operator!=(const Matrix< N, M, T > &other) const
Definition: matrix.h:171
Matrix::Matrix
Matrix()
Definition: matrix.h:35