libpromeki main
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
matrix3x3.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <cmath>
11#include <immintrin.h>
13
15
24class Matrix3x3 {
25 public:
27 static constexpr float IdentityMatrix[3][3] = {
28 {1.0f, 0.0f, 0.0f},
29 {0.0f, 1.0f, 0.0f},
30 {0.0f, 0.0f, 1.0f}
31 };
32
40 static Matrix3x3 scalingMatrix(float scale_x, float scale_y, float scale_z) {
41 Matrix3x3 result;
42 result.data[0][0] = scale_x;
43 result.data[1][1] = scale_y;
44 result.data[2][2] = scale_z;
45 return result;
46 }
47
54 static Matrix3x3 rotationMatrix(float angle, char axis) {
55 Matrix3x3 result;
56 float cos_angle = std::cos(angle);
57 float sin_angle = std::sin(angle);
58 switch (axis) {
59 case 'x':
60 result.data[0][0] = 1.0f;
61 result.data[1][1] = cos_angle;
62 result.data[1][2] = -sin_angle;
63 result.data[2][1] = sin_angle;
64 result.data[2][2] = cos_angle;
65 break;
66 case 'y':
67 result.data[0][0] = cos_angle;
68 result.data[0][2] = sin_angle;
69 result.data[1][1] = 1.0f;
70 result.data[2][0] = -sin_angle;
71 result.data[2][2] = cos_angle;
72 break;
73 case 'z':
74 result.data[0][0] = cos_angle;
75 result.data[0][1] = -sin_angle;
76 result.data[1][0] = sin_angle;
77 result.data[1][1] = cos_angle;
78 result.data[2][2] = 1.0f;
79 break;
80 default:
81 // Invalid axis, return identity matrix
82 result.data[0][0] = 1.0f;
83 result.data[1][1] = 1.0f;
84 result.data[2][2] = 1.0f;
85 break;
86 }
87 return result;
88 }
89
92 zero();
93 }
94
99 Matrix3x3(float val[3][3]) {
100 set(val);
101 }
102
109 Matrix3x3 result;
110 for (int i = 0; i < 3; ++i) {
111 __m128 row = _mm_loadu_ps(data[i]);
113 __m128 sum = _mm_add_ps(row, other_row);
114 _mm_storeu_ps(result.data[i], sum);
115 }
116 return result;
117 }
118
125 Matrix3x3 result;
126 for (int i = 0; i < 3; ++i) {
127 __m128 row = _mm_loadu_ps(data[i]);
130 _mm_storeu_ps(result.data[i], diff);
131 }
132 return result;
133 }
134
141 Matrix3x3 result;
142 for (int i = 0; i < 3; ++i) {
143 for (int j = 0; j < 3; ++j) {
144 float sum = 0.0f;
145 for (int k = 0; k < 3; ++k) {
146 sum += data[i][k] * other.data[k][j];
147 }
148 result.data[i][j] = sum;
149 }
150 }
151 return result;
152 }
153
160 float dot(int row1, int row2) const {
161 __m128 vec1 = _mm_set_ps(0.0f, data[row1][2], data[row1][1], data[row1][0]);
162 __m128 vec2 = _mm_set_ps(0.0f, data[row2][2], data[row2][1], data[row2][0]);
166 return _mm_cvtss_f32(mul);
167 }
168
170 void zero() {
171 for(int i = 0; i < 3; ++i) {
172 for (int j = 0; j < 3; ++j) {
173 data[i][j] = 0.0f;
174 }
175 }
176 return;
177 }
178
183 void set(float val[3][3]) {
184 for (int i = 0; i < 3; ++i) {
185 for (int j = 0; j < 3; ++j) {
186 data[i][j] = val[i][j];
187 }
188 }
189 return;
190 }
191
197 Matrix3x3 result;
198 for (int i = 0; i < 3; ++i) {
199 for (int j = 0; j < 3; ++j) {
200 result.data[i][j] = data[j][i];
201 }
202 }
203 return result;
204 }
205
210 float determinant() const {
211 return data[0][0] * (data[1][1] * data[2][2] - data[1][2] * data[2][1]) -
212 data[0][1] * (data[1][0] * data[2][2] - data[1][2] * data[2][0]) +
213 data[0][2] * (data[1][0] * data[2][1] - data[1][1] * data[2][0]);
214 }
215
221 Matrix3x3 result;
222 float det = determinant();
223 if (det == 0.0f) {
224 // Singular matrix, inverse does not exist
225 return result; // Return zero matrix
226 }
227 float inv_det = 1.0f / det;
228 result.data[0][0] = (data[1][1] * data[2][2] - data[1][2] * data[2][1]) * inv_det;
229 result.data[0][1] = (data[0][2] * data[2][1] - data[0][1] * data[2][2]) * inv_det;
230 result.data[0][2] = (data[0][1] * data[1][2] - data[0][2] * data[1][1]) * inv_det;
231 result.data[1][0] = (data[1][2] * data[2][0] - data[1][0] * data[2][2]) * inv_det;
232 result.data[1][1] = (data[0][0] * data[2][2] - data[0][2] * data[2][0]) * inv_det;
233 result.data[1][2] = (data[0][2] * data[1][0] - data[0][0] * data[1][2]) * inv_det;
234 result.data[2][0] = (data[1][0] * data[2][1] - data[1][1] * data[2][0]) * inv_det;
235 result.data[2][1] = (data[0][1] * data[2][0] - data[0][0] * data[2][1]) * inv_det;
236 result.data[2][2] = (data[0][0] * data[1][1] - data[0][1] * data[1][0]) * inv_det;
237 return result;
238 }
239
244 float trace() const {
245 return data[0][0] + data[1][1] + data[2][2];
246 }
247
254 Matrix3x3 result;
255 for (int i = 0; i < 3; ++i) {
256 for (int j = 0; j < 3; ++j) {
257 result.data[i][j] = data[i][j] * scalar;
258 }
259 }
260 return result;
261
262 }
263
270 Matrix3x3 result;
271 if (scalar != 0.0f) {
272 float inv_scalar = 1.0f / scalar;
273 for (int i = 0; i < 3; ++i) {
274 for (int j = 0; j < 3; ++j) {
275 result.data[i][j] = data[i][j] * inv_scalar;
276 }
277 }
278 }
279 return result;
280 }
281
283 bool operator==(const Matrix3x3& other) const {
284 for (int i = 0; i < 3; ++i) {
285 for (int j = 0; j < 3; ++j) {
286 if (data[i][j] != other.data[i][j]) {
287 return false;
288 }
289 }
290 }
291 return true;
292 }
293
295 bool operator!=(const Matrix3x3& other) const {
296 return !(*this == other);
297 }
298
299
306 float get(int row, int col) const {
307 if (row >= 0 && row < 3 && col >= 0 && col < 3) {
308 return data[row][col];
309 }
310 return 0.0f; // Invalid row or column, return 0.0f
311 }
312
319 void set(int row, int col, float value) {
320 if (row >= 0 && row < 3 && col >= 0 && col < 3) {
321 data[row][col] = value;
322 }
323 }
324
331 Matrix3x3 result;
332 for (int i = 0; i < 3; ++i) {
333 __m128 row = _mm_set_ps(0.0f, data[i][2], data[i][1], data[i][0]);
334 __m128 other_row = _mm_set_ps(0.0f, other.data[i][2], other.data[i][1], other.data[i][0]);
336 _mm_storeu_ps(result.data[i], mul);
337 }
338 return result;
339 }
340
350 Matrix3x3 result;
351 for (int i = 0; i < 3; ++i) {
352 __m128 row = _mm_set_ps(0.0f, data[i][2], data[i][1], data[i][0]);
353 __m128 other_row = _mm_set_ps(0.0f, other.data[i][2], other.data[i][1], other.data[i][0]);
354 // Create a mask to handle division by zero
357 // Apply the mask to avoid NaN values due to division by zero
359 _mm_storeu_ps(result.data[i], div);
360 }
361 return result;
362 }
363
368 void vectorTransform(float vector[3]) const {
369 float result[3];
370 result[0] = data[0][0] * vector[0] + data[0][1] * vector[1] + data[0][2] * vector[2];
371 result[1] = data[1][0] * vector[0] + data[1][1] * vector[1] + data[1][2] * vector[2];
372 result[2] = data[2][0] * vector[0] + data[2][1] * vector[1] + data[2][2] * vector[2];
373 vector[0] = result[0];
374 vector[1] = result[1];
375 vector[2] = result[2];
376 }
377
378 private:
379 float data[3][3];
380};
381
382
384
Dynamic array container wrapping std::vector.
Definition list.h:40
T * data() noexcept
Returns a pointer to the underlying contiguous storage.
Definition list.h:286
A 3x3 floating-point matrix with SSE-accelerated operations.
Definition matrix3x3.h:24
static Matrix3x3 scalingMatrix(float scale_x, float scale_y, float scale_z)
Creates a diagonal scaling matrix.
Definition matrix3x3.h:40
Matrix3x3 inverse() const
Computes the inverse of this matrix.
Definition matrix3x3.h:220
float dot(int row1, int row2) const
Computes the dot product of two rows in this matrix.
Definition matrix3x3.h:160
void vectorTransform(float vector[3]) const
Transforms a 3-element vector by this matrix in place.
Definition matrix3x3.h:368
Matrix3x3(float val[3][3])
Constructs a matrix from a 3x3 float array.
Definition matrix3x3.h:99
void set(float val[3][3])
Copies values from a 3x3 float array into this matrix.
Definition matrix3x3.h:183
static constexpr float IdentityMatrix[3][3]
The 3x3 identity matrix constant.
Definition matrix3x3.h:27
Matrix3x3 transpose() const
Returns the transpose of this matrix.
Definition matrix3x3.h:196
float determinant() const
Computes the determinant of this matrix.
Definition matrix3x3.h:210
Matrix3x3 operator*(const Matrix3x3 &other) const
Returns the matrix product of two matrices.
Definition matrix3x3.h:140
void set(int row, int col, float value)
Sets the element at the given row and column.
Definition matrix3x3.h:319
bool operator!=(const Matrix3x3 &other) const
Returns true if any element differs from the other matrix.
Definition matrix3x3.h:295
float trace() const
Computes the trace (sum of diagonal elements) of this matrix.
Definition matrix3x3.h:244
bool operator==(const Matrix3x3 &other) const
Returns true if all elements are equal to the other matrix.
Definition matrix3x3.h:283
Matrix3x3()
Constructs a zero-initialized matrix.
Definition matrix3x3.h:91
float get(int row, int col) const
Returns the element at the given row and column.
Definition matrix3x3.h:306
Matrix3x3 operator/(float scalar) const
Divides every element by a scalar.
Definition matrix3x3.h:269
Matrix3x3 elementMultiply(const Matrix3x3 &other) const
Returns the Hadamard (element-wise) product of two matrices.
Definition matrix3x3.h:330
Matrix3x3 operator-(const Matrix3x3 &other) const
Returns the element-wise difference of two matrices.
Definition matrix3x3.h:124
Matrix3x3 operator+(const Matrix3x3 &other) const
Returns the element-wise sum of two matrices.
Definition matrix3x3.h:108
void zero()
Sets all matrix elements to zero.
Definition matrix3x3.h:170
static Matrix3x3 rotationMatrix(float angle, char axis)
Creates a rotation matrix around the specified axis.
Definition matrix3x3.h:54
Matrix3x3 operator*(float scalar) const
Multiplies every element by a scalar.
Definition matrix3x3.h:253
Matrix3x3 elementDivide(const Matrix3x3 &other) const
Returns the element-wise quotient of two matrices.
Definition matrix3x3.h:349
#define PROMEKI_NAMESPACE_BEGIN
Starts a promeki namespace block.
Definition namespace.h:14
#define PROMEKI_NAMESPACE_END
Ends a promeki namespace block.
Definition namespace.h:19
const T & value(const Result< T > &r)
Returns the value from a Result.
Definition result.h:56