YAGE  v0.1.4.0
Yet Another Game Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix.h
Go to the documentation of this file.
1 
12 #ifndef YAGE_MATH_MATRIX_H
13 #define YAGE_MATH_MATRIX_H
14 
15 #include <algorithm>
16 #include <exception>
17 #include <iostream>
18 #include <sstream>
19 #include <string>
20 #include <vector>
21 
22 namespace yage
23 {
24 
25 template <int Rows, int Cols, class Type>
26 class Matrix;
27 
35 namespace details
36 {
37 
46 template <int Rows, int Cols, class Type>
47 class Row
48 {
49 private:
50  Matrix<Rows, Cols, Type> *parent_;
51  int index_;
52 
53 public:
55  : parent_(parent), index_(index)
56  {
57  }
58 
59  Type &operator[](int col)
60  {
61  // The index is the y-position of the element in the matrix
62  return parent_->data_[index_ * Cols + col];
63  }
64 
65  const Type &operator[](int col) const
66  {
67  return parent_->data_[index_ * Cols + col];
68  }
69 };
70 
71 } // namespace details
72 
75 template <int Rows = 4, int Cols = 4, class Type = double>
76 class Matrix
77 {
78  // friended with the row class so that it can access protected member data.
79  friend class details::Row<Rows, Cols, Type>;
80 
81 protected:
83  std::vector<Type> data_;
84 
85 public:
87  Matrix<Rows, Cols, Type>() : data_(Rows * Cols) {}
88  Matrix<Rows, Cols, Type>(const std::vector<Type> &data) : data_(data) {}
89 
91  int rowSize() const { return Rows; }
92 
94  int colSize() const { return Cols; }
95 
102  {
103  Matrix<1, Cols, Type> rowMatrix;
104  for (int i = 0; i < Cols; ++i) {
105  rowMatrix[0][i] = data_[row][i];
106  }
107  return rowMatrix;
108  }
109 
116  {
117  Matrix<Rows, 1, Type> colMatrix;
118  for (int i = 0; i < Rows; ++i) {
119  colMatrix[i][0] = data_[i][col];
120  }
121  return colMatrix;
122  }
123 
128  typename std::vector<Type>::iterator begin() { return data_.begin(); }
129 
134  typename std::vector<Type>::iterator end() { return data_.end(); }
135 
142  virtual std::string toString() const
143  {
144  std::stringstream ss;
145  ss << '[';
146  for (int i = 0; i < Rows - 1; ++i) {
147  ss << '[';
148  for (int j = 0; j < Cols - 1; ++j) {
149  ss << data_[i * Cols + j] << ' ';
150  }
151  ss << data_[(Rows - 1) * Cols + Cols - 1] << "],";
152  }
153  ss << '[';
154  for (int j = 0; j < Cols - 1; ++j) {
155  ss << data_[(Rows - 1) * Cols + j] << ' ';
156  }
157  ss << data_[(Rows - 1) * Cols + Cols - 1] << "]]";
158  return ss.str();
159  }
160 
162  {
163  return details::Row<Rows, Cols, Type>(this, row);
164  }
165 
167  {
169  row);
170  }
171 
173  {
174  std::vector<Type> out;
175  out.reserve(data_.size());
176  std::transform(data_.begin(), data_.end(), rhs.data_.begin(),
177  std::back_inserter(out),
178  [](Type a, Type b) { return a + b; });
179  data_ = std::move(out);
180  return *this;
181  }
182 
184  {
185  std::vector<Type> out;
186  out.reserve(data_.size());
187  std::transform(data_.begin(), data_.end(), rhs.begin(),
188  std::back_inserter(out),
189  [](Type a, Type b) { return a - b; });
190  data_ = std::move(out);
191  return *this;
192  }
193 };
194 
195 template <int M, int N, class T>
197 {
198  lhs += rhs;
199  return lhs;
200 }
201 
202 template <int M, int N, class T>
204 {
205  lhs -= rhs;
206  return lhs;
207 }
208 
209 template <int M, int N, class T>
211 {
212  for (auto &data : lhs) {
213  data += rhs;
214  }
215  return lhs;
216 }
217 
218 template <int M, int N, class T>
220 {
221  for (auto &data : rhs) {
222  data += lhs;
223  }
224  return rhs;
225 }
226 
227 template <int M, int N, class T>
229 {
230  for (auto &data : lhs) {
231  data -= rhs;
232  }
233  return lhs;
234 }
235 
236 template <int M, int N, class T>
238 {
239  for (auto &data : rhs) {
240  data = lhs - data;
241  }
242  return rhs;
243 }
244 
245 template <int M, int N, class T>
247 {
248  for (auto &data : lhs) {
249  data *= rhs;
250  }
251  return lhs;
252 }
253 
254 template <int M, int N, class T>
256 {
257  for (auto &data : rhs) {
258  data *= lhs;
259  }
260  return rhs;
261 }
262 
263 template <int M, int N, class T>
265 {
266  for (auto &data : lhs) {
267  data /= rhs;
268  }
269  return lhs;
270 }
271 
272 template <int M, int N, class T>
273 bool operator==(const Matrix<M, N, T> &lhs, const Matrix<M, N, T> &rhs)
274 {
275  for (int i = 0; i < M; ++i) {
276  for (int j = 0; j < N; ++j) {
277  if (lhs[i][j] != rhs[i][j]) {
278  return false;
279  }
280  }
281  }
282  return true;
283 }
284 
285 template <int M, int N, class T>
286 std::ostream &operator<<(std::ostream &os, const Matrix<M, N, T> &mat)
287 {
288  return os << mat.toString();
289 }
290 
291 template <int Rows = 2, class Type = double>
292 class Vector : public Matrix<Rows, 1, Type>
293 {
294 public:
297  : Matrix<Rows, 1, Type>(other)
298  {
299  }
300 
301  Vector<Rows, Type>(const std::vector<Type> &data)
302  : Matrix<Rows, 1, Type>(data)
303  {
304  }
305 
306  Type &operator[](int col) { return this->data_[col]; }
307 
308  const Type &operator[](int col) const { return this->data_[col]; }
309 
310  std::string toString() const override
311  {
312  std::stringstream ss;
313  ss << "[";
314  for (std::size_t i = 0; i < this->data_.size() - 1; ++i) {
315  ss << this->data_[i] << " ";
316  }
317  ss << this->data_[this->data_.size() - 1] << "]";
318  return ss.str();
319  }
320 };
321 
326 template <typename Type = double>
327 class Vector2 : public Vector<2, Type>
328 {
329 public:
331  Vector2<Type>(const std::vector<Type> &data) : Vector<2, Type>(data) {}
332 
333  Vector2<Type>(Type x, Type y)
334  {
335  this->data_[0] = x;
336  this->data_[1] = y;
337  }
338 
340 
341  Type &x() { return this->data_[0]; }
342  const Type &x() const { return this->data_[0]; }
343 
344  Type &y() { return this->data_[1]; }
345  const Type &y() const { return this->data_[1]; }
346 };
347 
352 template <typename Type = double>
353 class Vector3 : public Vector<3, Type>
354 {
355 public:
356  Type &x, &y, &z;
357 
359 
360  Vector3<Type>(std::vector<Type> data)
361  : Vector<3, Type>(data), x(this->data_[0]), y(this->data_[1]),
362  z(this->data_[2])
363  {
364  }
365 
366  Vector3<Type>(Type x_in, Type y_in, Type z_in)
367  : Vector<3, Type>({x_in, y_in, z_in}), x(this->data_[0]),
368  y(this->data_[1]), z(this->data_[2])
369  {
370  }
371 };
372 
375 template <typename Type = double>
376 class Vector4 : public Vector<4, Type>
377 {
378 public:
379  Type &x, &y, &z, &w;
380 
382 
383  Vector4<Type>(std::vector<Type> data)
384  : Vector<4, Type>(data), x(this->data_[0]), y(this->data_[1]),
385  z(this->data_[2]), w(this->data_[3])
386  {
387  }
388 
389  Vector4<Type>(Type x_in, Type y_in, Type z_in, Type w_in)
390  : Vector<4, Type>({x_in, y_in, z_in, w_in}), x(this->data_[0]),
391  y(this->data_[1]), z(this->data_[2]), w(this->data_[3])
392  {
393  }
394 };
395 
401 
407 
413 
419 namespace matrix
420 {
421 
426 template <int M, int N, class T>
428 {
429  Matrix<N, M, T> trans;
430  for (int i = 0; i < M; ++i) {
431  for (int j = 0; j < N; ++j) {
432  trans[j][i] = m[i][j];
433  }
434  }
435  return trans;
436 }
437 
442 template <int R, class T>
443 T dot(const Matrix<R, 1, T> &m1, const Matrix<R, 1, T> &m2)
444 {
445  T sum = 0;
446  for (int i = 0; i < R; ++i) {
447  sum += m1[i][0] * m2[i][0];
448  }
449  return sum;
450 }
451 
458 template <int M, int N, int P, int Q, class T>
460 {
462  if (N != P) {
463  throw std::runtime_error(
464  "Matrices don't have the right dimensions for multiplication");
465  }
466 
467  Matrix<M, Q, T> res;
468 
471  for (int i = 0; i < M; ++i) {
472  for (int j = 0; j < Q; ++j) {
473  res[i][j] = dot(transpose(m1.getRow(i)), m2.getCol(j));
474  }
475  }
476 
477  return res;
478 }
479 
480 } // namespace matrix
481 
482 } // namespace yage
483 
484 #endif
Matrix< M, N, T > operator/(Matrix< M, N, T > lhs, const T &rhs)
Definition: matrix.h:264
Matrix< 1, Cols, Type > getRow(int row) const
Return the row specified row as a Matrix with only one row.
Definition: matrix.h:101
Type & z
Definition: matrix.h:379
Definition: matrix.h:47
Matrix< M, N, T > operator*(Matrix< M, N, T > lhs, const T &rhs)
Definition: matrix.h:246
int rowSize() const
Returns the row size of the Matrix.
Definition: matrix.h:91
z(this->data_[2])
Definition: matrix.h:368
2D Vector class.
Definition: matrix.h:327
bool operator==(const Matrix< M, N, T > &lhs, const Matrix< M, N, T > &rhs)
Definition: matrix.h:273
Type & y
Definition: matrix.h:356
std::vector< Type >::iterator end()
Iterator support for the end.
Definition: matrix.h:134
Type & x
Definition: matrix.h:356
Type & operator[](int col)
Definition: matrix.h:306
Type & y
Definition: matrix.h:379
std::vector< Type > data_
Vector containing the data of the matrix.
Definition: matrix.h:83
Matrix< M, Q, T > multiply(const Matrix< M, N, T > &m1, const Matrix< P, Q, T > &m2)
Multiplies two matrices together.
Definition: matrix.h:459
Type & y()
Definition: matrix.h:344
Type & operator[](int col)
Definition: matrix.h:59
Matrix< Rows, 1, Type > getCol(int col) const
Get a specific column in a column vector.
Definition: matrix.h:115
const Type & operator[](int col) const
Definition: matrix.h:65
w(this->data_[3])
Definition: matrix.h:391
const Type & x() const
Definition: matrix.h:342
Type & x
Definition: matrix.h:379
Matrix< N, M, T > transpose(const Matrix< M, N, T > &m)
Transposes a matrix and returns the result.
Definition: matrix.h:427
int colSize() const
Returns the column size of the Matrix.
Definition: matrix.h:94
const Type & operator[](int col) const
Definition: matrix.h:308
Matrix< Rows, Cols, Type > & operator-=(const Matrix< Rows, Cols, Type > &rhs)
Definition: matrix.h:183
3D Vector class.
Definition: matrix.h:353
Type & x()
Definition: matrix.h:341
details::Row< Rows, Cols, Type > operator[](int row) const
Definition: matrix.h:166
details::Row< Rows, Cols, Type > operator[](int row)
Definition: matrix.h:161
Matrix< M, N, T > operator+(Matrix< M, N, T > lhs, const Matrix< M, N, T > &rhs)
Definition: matrix.h:196
Definition: matrix.h:292
Matrix< M, N, T > operator-(Matrix< M, N, T > lhs, const Matrix< M, N, T > &rhs)
Definition: matrix.h:203
virtual std::string toString() const
Prints out the matrix, but can also be implemented by other classes to print data differently...
Definition: matrix.h:142
Matrix< Rows, Cols, Type > & operator+=(const Matrix< Rows, Cols, Type > &rhs)
Definition: matrix.h:172
Base Matrix class used by other similar classes.
Definition: matrix.h:26
T dot(const Matrix< R, 1, T > &m1, const Matrix< R, 1, T > &m2)
Returns the dot product between two vectors.
Definition: matrix.h:443
Type & w
Definition: matrix.h:379
const Type & y() const
Definition: matrix.h:345
std::string toString() const override
Prints out the matrix, but can also be implemented by other classes to print data differently...
Definition: matrix.h:310
4D Vector class
Definition: matrix.h:376
std::vector< Type >::iterator begin()
Iterator support for the start.
Definition: matrix.h:128
Type & z
Definition: matrix.h:356