Pioneer
matrix3x3.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _MATRIX3X3_H
5 #define _MATRIX3X3_H
6 
7 #include "vector3.h"
8 #include <math.h>
9 #include <stdio.h>
10 #include <type_traits>
11 
12 template <typename T>
13 class matrix3x3 {
14 private:
15  T cell[9];
16  using other_float_t = typename std::conditional<std::is_same<T, float>::value, double, float>::type;
17 
18 public:
19  matrix3x3() {}
20  explicit matrix3x3(T val)
21  {
22  cell[0] = cell[1] = cell[2] = cell[3] = cell[4] = cell[5] = cell[6] =
23  cell[7] = cell[8] = val;
24  }
25  explicit matrix3x3(const T *vals)
26  {
27  memcpy(cell, vals, sizeof(T) * 9);
28  }
30  {
31  for (int i = 0; i < 9; i++)
32  cell[i] = T(m[i]);
33  }
34 
35  T &operator[](const size_t i) { return cell[i]; } // used for serializing
36  const T &operator[](const size_t i) const { return cell[i]; }
37 
38  const T *Data() const { return cell; }
39  T *Data() { return cell; }
40 
41  vector3<T> VectorX() const { return vector3<T>(cell[0], cell[3], cell[6]); }
42  vector3<T> VectorY() const { return vector3<T>(cell[1], cell[4], cell[7]); }
43  vector3<T> VectorZ() const { return vector3<T>(cell[2], cell[5], cell[8]); }
44 
46  {
47  matrix3x3 m;
48  m.cell[1] = m.cell[2] = m.cell[3] = m.cell[5] = m.cell[6] = m.cell[7] = 0.0f;
49  m.cell[0] = m.cell[4] = m.cell[8] = 1.0f;
50  return m;
51  }
52  static matrix3x3 Scale(T x, T y, T z)
53  {
54  matrix3x3 m;
55  m.cell[1] = m.cell[2] = m.cell[3] = m.cell[5] = m.cell[6] = m.cell[7] = 0.0f;
56  m.cell[0] = x;
57  m.cell[4] = y;
58  m.cell[8] = z;
59  return m;
60  }
61  static matrix3x3 Scale(T scale)
62  {
63  matrix3x3 m;
64  m.cell[1] = m.cell[2] = m.cell[3] = m.cell[5] = m.cell[6] = m.cell[7] = 0.0f;
65  m.cell[0] = m.cell[4] = m.cell[8] = scale;
66  return m;
67  }
68  static matrix3x3 FromVectors(const vector3<T> &rx, const vector3<T> &ry, const vector3<T> &rz)
69  {
70  matrix3x3 m;
71  m[0] = rx.x;
72  m[1] = ry.x;
73  m[2] = rz.x;
74  m[3] = rx.y;
75  m[4] = ry.y;
76  m[5] = rz.y;
77  m[6] = rx.z;
78  m[7] = ry.z;
79  m[8] = rz.z;
80  return m;
81  }
82  static matrix3x3 FromVectors(const vector3<T> &rx, const vector3<T> &ry)
83  {
84  return FromVectors(rx, ry, rx.Cross(ry));
85  }
86  // (x,y,z) must be normalized
87  static matrix3x3 Rotate(T ang, const vector3<T> &v)
88  {
89  matrix3x3 m;
90  T c = cos(ang);
91  T s = sin(ang);
92  m[0] = v.x * v.x * (1 - c) + c;
93  m[1] = v.x * v.y * (1 - c) - v.z * s;
94  m[2] = v.x * v.z * (1 - c) + v.y * s;
95  m[3] = v.y * v.x * (1 - c) + v.z * s;
96  m[4] = v.y * v.y * (1 - c) + c;
97  m[5] = v.y * v.z * (1 - c) - v.x * s;
98  m[6] = v.x * v.z * (1 - c) - v.y * s;
99  m[7] = v.y * v.z * (1 - c) + v.x * s;
100  m[8] = v.z * v.z * (1 - c) + c;
101  return m;
102  }
103  // Note: these three are backwards compared to the right-handed rotation convention
104  static matrix3x3 RotateX(T radians)
105  {
106  matrix3x3 m;
107  T c = cos(radians);
108  T s = sin(radians);
109  m[0] = 1.0f;
110  m[1] = 0;
111  m[2] = 0;
112  m[3] = 0;
113  m[4] = c;
114  m[5] = s;
115  m[6] = 0;
116  m[7] = -s;
117  m[8] = c;
118  return m;
119  }
120  static matrix3x3 RotateY(T radians)
121  {
122  matrix3x3 m;
123  T c = cos(radians);
124  T s = sin(radians);
125  m[0] = c;
126  m[1] = 0;
127  m[2] = -s;
128  m[3] = 0;
129  m[4] = 1.0;
130  m[5] = 0;
131  m[6] = s;
132  m[7] = 0;
133  m[8] = c;
134  return m;
135  }
136  static matrix3x3 RotateZ(T radians)
137  {
138  matrix3x3 m;
139  T c = cos(radians);
140  T s = sin(radians);
141  m[0] = c;
142  m[1] = s;
143  m[2] = 0;
144  m[3] = -s;
145  m[4] = c;
146  m[5] = 0;
147  m[6] = 0;
148  m[7] = 0;
149  m[8] = 1.0;
150  return m;
151  }
152 
153  friend matrix3x3 operator*(const matrix3x3 &a, const matrix3x3 &b)
154  {
155  matrix3x3 m;
156  m.cell[0] = a.cell[0] * b.cell[0] + a.cell[1] * b.cell[3] + a.cell[2] * b.cell[6];
157  m.cell[1] = a.cell[0] * b.cell[1] + a.cell[1] * b.cell[4] + a.cell[2] * b.cell[7];
158  m.cell[2] = a.cell[0] * b.cell[2] + a.cell[1] * b.cell[5] + a.cell[2] * b.cell[8];
159 
160  m.cell[3] = a.cell[3] * b.cell[0] + a.cell[4] * b.cell[3] + a.cell[5] * b.cell[6];
161  m.cell[4] = a.cell[3] * b.cell[1] + a.cell[4] * b.cell[4] + a.cell[5] * b.cell[7];
162  m.cell[5] = a.cell[3] * b.cell[2] + a.cell[4] * b.cell[5] + a.cell[5] * b.cell[8];
163 
164  m.cell[6] = a.cell[6] * b.cell[0] + a.cell[7] * b.cell[3] + a.cell[8] * b.cell[6];
165  m.cell[7] = a.cell[6] * b.cell[1] + a.cell[7] * b.cell[4] + a.cell[8] * b.cell[7];
166  m.cell[8] = a.cell[6] * b.cell[2] + a.cell[7] * b.cell[5] + a.cell[8] * b.cell[8];
167  return m;
168  }
169  friend vector3<T> operator*(const matrix3x3 &a, const vector3<T> &v)
170  {
171  vector3<T> out;
172  out.x = a.cell[0] * v.x + a.cell[1] * v.y + a.cell[2] * v.z;
173  out.y = a.cell[3] * v.x + a.cell[4] * v.y + a.cell[5] * v.z;
174  out.z = a.cell[6] * v.x + a.cell[7] * v.y + a.cell[8] * v.z;
175  return out;
176  }
177  // V * M same as transpose(M) * V
178  friend vector3<T> operator*(const vector3<T> &v, const matrix3x3 &a)
179  {
180  vector3<T> out;
181  out.x = a.cell[0] * v.x + a.cell[3] * v.y + a.cell[6] * v.z;
182  out.y = a.cell[1] * v.x + a.cell[4] * v.y + a.cell[7] * v.z;
183  out.z = a.cell[2] * v.x + a.cell[5] * v.y + a.cell[8] * v.z;
184  return out;
185  }
187  {
188  matrix3x3 m;
189  m[0] = cell[0];
190  m[1] = cell[3];
191  m[2] = cell[6];
192  m[3] = cell[1];
193  m[4] = cell[4];
194  m[5] = cell[7];
195  m[6] = cell[2];
196  m[7] = cell[5];
197  m[8] = cell[8];
198  return m;
199  }
201  {
202 // computes the inverse of a matrix m
203 #define cell2d(x, y) cell[((y * 3) + x)]
204  const T det = cell2d(0, 0) * (cell2d(1, 1) * cell2d(2, 2) - cell2d(2, 1) * cell2d(1, 2)) -
205  cell2d(0, 1) * (cell2d(1, 0) * cell2d(2, 2) - cell2d(1, 2) * cell2d(2, 0)) +
206  cell2d(0, 2) * (cell2d(1, 0) * cell2d(2, 1) - cell2d(1, 1) * cell2d(2, 0));
207 
208  const T invdet = T(1.0) / det;
209 
210  matrix3x3 minv; // inverse of matrix m
211 #define idx2d(x, y) ((y * 3) + x)
212  minv[idx2d(0, 0)] = (cell2d(1, 1) * cell2d(2, 2) - cell2d(2, 1) * cell2d(1, 2)) * invdet;
213  minv[idx2d(0, 1)] = (cell2d(0, 2) * cell2d(2, 1) - cell2d(0, 1) * cell2d(2, 2)) * invdet;
214  minv[idx2d(0, 2)] = (cell2d(0, 1) * cell2d(1, 2) - cell2d(0, 2) * cell2d(1, 1)) * invdet;
215  minv[idx2d(1, 0)] = (cell2d(1, 2) * cell2d(2, 0) - cell2d(1, 0) * cell2d(2, 2)) * invdet;
216  minv[idx2d(1, 1)] = (cell2d(0, 0) * cell2d(2, 2) - cell2d(0, 2) * cell2d(2, 0)) * invdet;
217  minv[idx2d(1, 2)] = (cell2d(1, 0) * cell2d(0, 2) - cell2d(0, 0) * cell2d(1, 2)) * invdet;
218  minv[idx2d(2, 0)] = (cell2d(1, 0) * cell2d(2, 1) - cell2d(2, 0) * cell2d(1, 1)) * invdet;
219  minv[idx2d(2, 1)] = (cell2d(2, 0) * cell2d(0, 1) - cell2d(0, 0) * cell2d(2, 1)) * invdet;
220  minv[idx2d(2, 2)] = (cell2d(0, 0) * cell2d(1, 1) - cell2d(1, 0) * cell2d(0, 1)) * invdet;
221  return minv;
222  }
224  {
225  vector3<T> x = VectorX().Normalized();
226  vector3<T> y = VectorZ().Cross(x).Normalized();
227  return FromVectors(x, y);
228  }
229  void Renormalize()
230  {
231  *this = Normalized();
232  }
233  void Print() const
234  {
235  for (int i = 0; i < 3; i++) {
236  printf("%.2f %.2f %.2f\n", cell[3 * i], cell[3 * i + 1], cell[3 * i + 2]);
237  }
238  printf("\n");
239  }
240 };
241 
244 
245 static const matrix3x3f matrix3x3fIdentity(matrix3x3f::Identity());
246 static const matrix3x3d matrix3x3dIdentity(matrix3x3d::Identity());
247 
248 #endif /* _MATRIX3x3_H */
double val
Definition: PrecalcPath.cpp:40
Definition: matrix3x3.h:13
vector3< T > VectorY() const
Definition: matrix3x3.h:42
T & operator[](const size_t i)
Definition: matrix3x3.h:35
friend matrix3x3 operator*(const matrix3x3 &a, const matrix3x3 &b)
Definition: matrix3x3.h:153
friend vector3< T > operator*(const matrix3x3 &a, const vector3< T > &v)
Definition: matrix3x3.h:169
static matrix3x3 Identity()
Definition: matrix3x3.h:45
void Print() const
Definition: matrix3x3.h:233
const T & operator[](const size_t i) const
Definition: matrix3x3.h:36
static matrix3x3 RotateY(T radians)
Definition: matrix3x3.h:120
static matrix3x3 RotateX(T radians)
Definition: matrix3x3.h:104
const T * Data() const
Definition: matrix3x3.h:38
matrix3x3 Normalized() const
Definition: matrix3x3.h:223
matrix3x3()
Definition: matrix3x3.h:19
static matrix3x3 Scale(T scale)
Definition: matrix3x3.h:61
T * Data()
Definition: matrix3x3.h:39
matrix3x3(T val)
Definition: matrix3x3.h:20
matrix3x3 Transpose() const
Definition: matrix3x3.h:186
static matrix3x3 FromVectors(const vector3< T > &rx, const vector3< T > &ry)
Definition: matrix3x3.h:82
static matrix3x3 Rotate(T ang, const vector3< T > &v)
Definition: matrix3x3.h:87
matrix3x3 Inverse() const
Definition: matrix3x3.h:200
void Renormalize()
Definition: matrix3x3.h:229
static matrix3x3 Scale(T x, T y, T z)
Definition: matrix3x3.h:52
matrix3x3(const matrix3x3< other_float_t > &m)
Definition: matrix3x3.h:29
static matrix3x3 FromVectors(const vector3< T > &rx, const vector3< T > &ry, const vector3< T > &rz)
Definition: matrix3x3.h:68
static matrix3x3 RotateZ(T radians)
Definition: matrix3x3.h:136
friend vector3< T > operator*(const vector3< T > &v, const matrix3x3 &a)
Definition: matrix3x3.h:178
vector3< T > VectorZ() const
Definition: matrix3x3.h:43
vector3< T > VectorX() const
Definition: matrix3x3.h:41
matrix3x3(const T *vals)
Definition: matrix3x3.h:25
Definition: vector3.h:16
T y
Definition: vector3.h:18
T x
Definition: vector3.h:18
T z
Definition: vector3.h:18
vector3 Cross(const vector3 &b) const
Definition: vector3.h:117
matrix3x3< double > matrix3x3d
Definition: matrix3x3.h:243
matrix3x3< float > matrix3x3f
Definition: matrix3x3.h:242
#define idx2d(x, y)
#define cell2d(x, y)