Pioneer
Loading...
Searching...
No Matches
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
12template <typename T>
13class matrix3x3 {
14private:
15 T cell[9];
16 using other_float_t = typename std::conditional<std::is_same<T, float>::value, double, float>::type;
17
18public:
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 }
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
245static const matrix3x3f matrix3x3fIdentity(matrix3x3f::Identity());
246static const matrix3x3d matrix3x3dIdentity(matrix3x3d::Identity());
247
248#endif /* _MATRIX3x3_H */
double val
Definition PrecalcPath.cpp:40
Definition matrix3x3.h:13
friend vector3< T > operator*(const matrix3x3 &a, const vector3< T > &v)
Definition matrix3x3.h:169
T * Data()
Definition matrix3x3.h:39
vector3< T > VectorZ() const
Definition matrix3x3.h:43
friend matrix3x3 operator*(const matrix3x3 &a, const matrix3x3 &b)
Definition matrix3x3.h:153
T & operator[](const size_t i)
Definition matrix3x3.h:35
vector3< T > VectorX() const
Definition matrix3x3.h:41
static matrix3x3 Identity()
Definition matrix3x3.h:45
void Print() const
Definition matrix3x3.h:233
vector3< T > VectorY() const
Definition matrix3x3.h:42
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
matrix3x3 Normalized() const
Definition matrix3x3.h:223
matrix3x3()
Definition matrix3x3.h:19
friend vector3< T > operator*(const vector3< T > &v, const matrix3x3 &a)
Definition matrix3x3.h:178
static matrix3x3 Scale(T scale)
Definition matrix3x3.h:61
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
const T * Data() const
Definition matrix3x3.h:38
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)