EHS
Mat3.h
Go to the documentation of this file.
1#pragma once
2
3#include "EHS.h"
4#include "Vec3.h"
5#include "Mat2.h"
6
7namespace ehs
8{
9 template<typename T = float>
10 class Mat3
11 {
12 private:
13 T data[9];
14
15 public:
17 {
18 for (UInt_8 i = 0; i < 9; ++i)
19 data[i] = 0;
20 }
21
22 template<typename C>
23 Mat3(const Mat2<C>& mat)
24 {
25 for (UInt_8 i = 0; i < 4; ++i)
26 data[i / 2 * 4 + i % 2] = mat.data[i];
27 }
28
29 template<typename C>
30 Mat3(const Mat3<C>& mat)
31 {
32 for (UInt_8 i = 0; i < 9; ++i)
33 data[i] = mat.data[i];
34 }
35
36 template<typename C>
38 {
39 if (this == &mat)
40 return *this;
41
42 for (UInt_8 i = 0; i < 9; ++i)
43 data[i] = mat.data[i];
44
45 return *this;
46 }
47
48 operator Mat2<T>() const
49 {
50 Mat2<T> result;
51
52 for (UInt_8 i = 0; i < 4; ++i)
53 result[i] = data[i / 2 * 4 + i % 2];
54
55 return result;
56 }
57
58 operator const T*() const
59 {
60 return data;
61 }
62
63 operator T*()
64 {
65 return data;
66 }
67
69 {
70 Vec3<T> result;
71 result.x = vec.x * data[0] + vec.y * data[3] + vec.z * data[6];
72 result.y = vec.x * data[1] + vec.y * data[4] + vec.z * data[7];
73 result.z = vec.x * data[2] + vec.y * data[5] + vec.z * data[8];
74
75 return result;
76 }
77
78 Mat3<T>& operator*=(const T scalar)
79 {
80 for (UInt_8 i = 0; i < 9; ++i)
81 data[i] *= scalar;
82
83 return *this;
84 }
85
86 Mat3<T> operator*(const T scalar) const
87 {
88 Mat3<T> result;
89 for (UInt_8 i = 0; i < 9; ++i)
90 result.data[i] = data[i] * scalar;
91
92 return result;
93 }
94
96 {
97 Mat3<T> old = *this;
98 for (UInt_8 i = 0; i < 9; ++i)
99 {
100 UInt_8 row = i / 3;
101 UInt_8 column = i % 3;
102 data[i] = 0;
103 data[i] += old.data[0 * 3 + column] * mat.data[row * 3 + 0];
104 data[i] += old.data[1 * 3 + column] * mat.data[row * 3 + 1];
105 data[i] += old.data[2 * 3 + column] * mat.data[row * 3 + 2];
106 }
107
108 return *this;
109 }
110
111 Mat3<T> operator*(const Mat3<T>& mat) const
112 {
113 Mat3<T> result;
114 for (UInt_8 i = 0; i < 9; ++i)
115 {
116 UInt_8 row = i / 3;
117 UInt_8 column = i % 3;
118 result.data[i] += data[0 * 3 + column] * mat.data[row * 3 + 0];
119 result.data[i] += data[1 * 3 + column] * mat.data[row * 3 + 1];
120 result.data[i] += data[2 * 3 + column] * mat.data[row * 3 + 2];
121 }
122
123 return result;
124 }
125
127 {
128 Mat3<T> result;
129 for (UInt_8 i = 0; i < 9; ++i)
130 result.data[i] = data[3 * (i % 3) + i / 3];
131
132 return result;
133 }
134
136 {
137 Mat3<T> old = *this;
138 for (UInt_8 i = 0; i < 9; ++i)
139 data[i] = old.data[3 * (i % 3) + i / 3];
140 }
141
143 {
144 Mat3<T> result;
145
146 for (UInt_8 r = 0; r < 3; ++r)
147 for (UInt_8 c = 0; c < 3; ++c)
148 result[3 * r + c] = Cut(r, c).GetDeterminant();
149
150 return result;
151 }
152
153 void Minor()
154 {
155 Mat3<T> old = *this;
156
157 for (UInt_8 r = 0; r < 3; ++r)
158 for (UInt_8 c = 0; c < 3; ++c)
159 data[3 * r + c] = old.Cut(r, c).GetDeterminant();
160 }
161
162 Mat2<T> Cut(const UInt_8 row, const UInt_8 column) const
163 {
164 Mat2<T> result;
165 UInt_8 index = 0;
166
167 for (UInt_8 r = 0; r < 3; ++r)
168 {
169 for (UInt_8 c = 0; c < 3; ++c)
170 {
171 if (r == row || c == column)
172 continue;
173
174 result[index++] = data[3 * r + c];
175 }
176 }
177
178 return result;
179 }
180
182 {
183 Mat3<T> cofactor = GetCofactor();
184 T result = 0;
185
186 for (UInt_8 c = 0; c < 3; ++c)
187 result += data[c] * cofactor[c];
188
189 return result;
190 }
191
193 {
194 Mat3<T> minor = GetMinor();
195 Mat3<T> result;
196
197 for (UInt_8 r = 0; r < 3; ++r)
198 {
199 for (UInt_8 c = 0; c < 3; ++c)
200 {
201 UInt_8 i = 3 * c + r;
202 result.data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
203 }
204 }
205
206 return result;
207 }
208
209 void Cofactor()
210 {
211 Mat3<T> minor = GetMinor();
212
213 for (UInt_8 r = 0; r < 3; ++r)
214 {
215 for (UInt_8 c = 0; c < 3; ++c)
216 {
217 UInt_8 i = 3 * c + r;
218 data[i] = minor.data[i] * Math::Pow<T>(-1, r + c);
219 }
220 }
221 }
222
224 {
225 return GetCofactor().GetTranspose();
226 }
227
228 void Adjugate()
229 {
230 Cofactor();
231 Transpose();
232 }
233
235 {
236 T det = GetDeterminant();
237 if (Math::ComCmp(det, 0))
238 return {};
239
240 return GetAdjugate() * (1 / det);
241 }
242
243 void Inverse()
244 {
245 T det = GetDeterminant();
246 if (Math::ComCmp(det, 0))
247 return;
248
249 Adjugate();
250 operator*=(1 / det);
251 }
252
254 {
255 Mat3<T> result;
256 result.data[0] = 1;
257 result.data[4] = 1;
258 result.data[8] = 1;
259 return result;
260 }
261
262 static Mat3<T> Scale(const Vec3<T>& scale)
263 {
264 Mat3<T> result;
265 result.data[0] = scale.x;
266 result.data[4] = scale.y;
267 result.data[8] = scale.z;
268
269 return result;
270 }
271
272 static Mat3<T> PitchRotate(const T angle)
273 {
274 T radians = Math::Rads(angle);
275
276 Mat3<T> result;
277 result.data[0] = 1;
278 result.data[4] = Math::Cos(radians);
279 result.data[5] = Math::Sin(radians);
280 result.data[7] = -Math::Sin(radians);
281 result.data[8] = Math::Cos(radians);
282
283 return result;
284 }
285
286 static Mat3<T> YawRotate(const T angle)
287 {
288 T radians = Math::Rads(angle);
289
290 Mat3<T> result;
291 result.data[0] = Math::Cos(radians);
292 result.data[2] = -Math::Sin(radians);
293 result.data[4] = 1;
294 result.data[6] = Math::Sin(radians);
295 result.data[8] = Math::Cos(radians);
296
297 return result;
298 }
299
300 static Mat3<T> RollRotate(const T angle)
301 {
302 T radians = Math::Rads(angle);
303
304 Mat3<T> result;
305 result.data[0] = Math::Cos(radians);
306 result.data[1] = Math::Sin(radians);
307 result.data[3] = -Math::Sin(radians);
308 result.data[4] = Math::Cos(radians);
309 result.data[8] = 1;
310
311 return result;
312 }
313
314 static Mat3<T> Rotate(const Vec3<T>& vec)
315 {
316 return YawRotate(vec.y) * RollRotate(vec.z) * PitchRotate(vec.x);
317 }
318 };
319
320 template class EHS_LIB_IO Mat3<float>;
321 template class EHS_LIB_IO Mat3<double>;
322
325}
Definition: Mat2.h:10
Definition: Mat3.h:11
void Cofactor()
Definition: Mat3.h:209
void Minor()
Definition: Mat3.h:153
Mat3< T > GetAdjugate() const
Definition: Mat3.h:223
static Mat3< T > PitchRotate(const T angle)
Definition: Mat3.h:272
T GetDeterminant() const
Definition: Mat3.h:181
static Mat3< T > Rotate(const Vec3< T > &vec)
Definition: Mat3.h:314
static Mat3< T > Identity()
Definition: Mat3.h:253
void Inverse()
Definition: Mat3.h:243
Vec3< T > operator*(Vec3< T > vec) const
Definition: Mat3.h:68
Mat3< T > operator*(const Mat3< T > &mat) const
Definition: Mat3.h:111
Mat3()
Definition: Mat3.h:16
Mat3< T > & operator*=(const T scalar)
Definition: Mat3.h:78
void Adjugate()
Definition: Mat3.h:228
static Mat3< T > Scale(const Vec3< T > &scale)
Definition: Mat3.h:262
Mat3< T > GetTranspose() const
Definition: Mat3.h:126
Mat3< T > operator*(const T scalar) const
Definition: Mat3.h:86
Mat3< T > & operator=(const Mat3< C > &mat)
Definition: Mat3.h:37
static Mat3< T > YawRotate(const T angle)
Definition: Mat3.h:286
Mat2< T > Cut(const UInt_8 row, const UInt_8 column) const
Definition: Mat3.h:162
static Mat3< T > RollRotate(const T angle)
Definition: Mat3.h:300
Mat3< T > & operator*=(const Mat3< T > &mat)
Definition: Mat3.h:95
Mat3< T > GetCofactor() const
Definition: Mat3.h:192
Mat3(const Mat3< C > &mat)
Definition: Mat3.h:30
Mat3< T > GetMinor() const
Definition: Mat3.h:142
Mat3< T > GetInverse() const
Definition: Mat3.h:234
Mat3(const Mat2< C > &mat)
Definition: Mat3.h:23
void Transpose()
Definition: Mat3.h:135
static T Rads(const T from)
Definition: Math.h:89
static R Sin(const R angle, const R precision=0.001)
Definition: Math.h:257
static R Cos(const R angle, const R precision=0.001)
Definition: Math.h:298
static bool ComCmp(float a, float b)
Combined absolute and relative tolerance comparison for single precision floats.
Definition: Math.cpp:26
Definition: Vec3.h:14
T x
Definition: Vec3.h:16
T z
Definition: Vec3.h:18
T y
Definition: Vec3.h:17
Definition: Anchor.h:6
unsigned char UInt_8
Definition: Types.h:43
Mat3< double > Mat3_d
Definition: Mat3.h:324
Mat3< float > Mat3_f
Definition: Mat3.h:323