JSim 2026.06.01-p(1)
Loading...
Searching...
No Matches
matrix.hpp
Go to the documentation of this file.
1// Copyright (c) JSim contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the LGPLv3 license file in the root directory of this project.
4
5#pragma once
6#include <cmath>
7#include <cassert>
8#include <limits>
9#include <iostream>
10#include <iomanip>
11
12#include "vector.hpp"
13#include "quaternion.hpp"
14
15namespace frcsim {
16
27struct alignas(16) Matrix3 {
28 double m[3][3]; // row-major
29
30 /* Constructors */
31
32 constexpr Matrix3() noexcept : m{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}} {}
33
34 constexpr Matrix3(double m00, double m01, double m02, double m10, double m11,
35 double m12, double m20, double m21, double m22) noexcept
36 : m{{m00, m01, m02}, {m10, m11, m12}, {m20, m21, m22}} {}
37
38 static constexpr Matrix3 identity() noexcept { return Matrix3(); }
39
40 static constexpr Matrix3 zero() noexcept {
41 return Matrix3(0, 0, 0, 0, 0, 0, 0, 0, 0);
42 }
43
44 /* Element access */
45
46 double* operator[](size_t i) {
47 assert(i < 3);
48 return m[i];
49 }
50
51 const double* operator[](size_t i) const {
52 assert(i < 3);
53 return m[i];
54 }
55
56 /* Matrix arithmetic */
57
58 constexpr Matrix3 operator+(const Matrix3& o) const noexcept {
59 Matrix3 r = zero();
60
61 for (int i = 0; i < 3; i++)
62 for (int j = 0; j < 3; j++)
63 r.m[i][j] = m[i][j] + o.m[i][j];
64
65 return r;
66 }
67
68 constexpr Matrix3 operator-(const Matrix3& o) const noexcept {
69 Matrix3 r = zero();
70
71 for (int i = 0; i < 3; i++)
72 for (int j = 0; j < 3; j++)
73 r.m[i][j] = m[i][j] - o.m[i][j];
74
75 return r;
76 }
77
78 constexpr Matrix3 operator*(double s) const noexcept {
79 Matrix3 r = zero();
80
81 for (int i = 0; i < 3; i++)
82 for (int j = 0; j < 3; j++)
83 r.m[i][j] = m[i][j] * s;
84
85 return r;
86 }
87
88 /* Matrix × Vector */
89
90 Vector3 operator*(const Vector3& v) const noexcept {
91 return Vector3(m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z,
92 m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
93 m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
94 }
95
96 /* Matrix × Matrix */
97
98 Matrix3 operator*(const Matrix3& o) const noexcept {
99 Matrix3 r = zero();
100
101 for (int i = 0; i < 3; i++)
102 for (int j = 0; j < 3; j++)
103 for (int k = 0; k < 3; k++)
104 r.m[i][j] += m[i][k] * o.m[k][j];
105
106 return r;
107 }
108
109 /* Transpose */
110
111 Matrix3 transpose() const noexcept {
112 return Matrix3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1],
113 m[0][2], m[1][2], m[2][2]);
114 }
115
116 /* Determinant */
117
118 double determinant() const noexcept {
119 return m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
120 m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) +
121 m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
122 }
123
124 /* Inverse */
125
127 Matrix3& out,
128 double eps = std::numeric_limits<double>::epsilon()) const noexcept {
129 double det = determinant();
130
131 if (std::abs(det) < eps)
132 return false;
133
134 double invDet = 1.0 / det;
135
136 Matrix3 r;
137
138 r.m[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) * invDet;
139 r.m[0][1] = (m[0][2] * m[2][1] - m[0][1] * m[2][2]) * invDet;
140 r.m[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * invDet;
141
142 r.m[1][0] = (m[1][2] * m[2][0] - m[1][0] * m[2][2]) * invDet;
143 r.m[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]) * invDet;
144 r.m[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) * invDet;
145
146 r.m[2][0] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]) * invDet;
147 r.m[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) * invDet;
148 r.m[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) * invDet;
149
150 out = r;
151 return true;
152 }
153
154 Matrix3 inverse() const noexcept {
155 Matrix3 r;
156 if (!tryInverse(r))
157 return identity(); // safe fallback for legacy callers
158
159 return r;
160 }
161
162 /* Rotation helper */
163
164 static Matrix3 fromQuaternion(const Quaternion& q) noexcept {
165 Matrix3 r;
166
167 q.toMatrix(r.m);
168
169 return r;
170 }
171
172 /* Comparison */
173
174 bool operator==(const Matrix3& o) const noexcept {
175 for (int i = 0; i < 3; i++)
176 for (int j = 0; j < 3; j++)
177 if (m[i][j] != o.m[i][j])
178 return false;
179
180 return true;
181 }
182
183 bool operator!=(const Matrix3& o) const noexcept { return !(*this == o); }
184
185 /* Debug output */
186
187 friend std::ostream& operator<<(std::ostream& os, const Matrix3& mat) {
188 os << std::fixed << std::setprecision(4);
189
190 for (int i = 0; i < 3; i++)
191 os << "[" << mat.m[i][0] << " " << mat.m[i][1] << " " << mat.m[i][2]
192 << "]\n";
193
194 return os;
195 }
196};
197
198/* Scalar multiply (left) */
199
200inline Matrix3 operator*(double s, const Matrix3& m) noexcept {
201 return m * s;
202}
203
204} // namespace frcsim
Definition vector.hpp:13
Vector3 operator*(double s, const Vector3 &v) noexcept
Left scalar multiplication helper (s * v).
Definition vector.hpp:412
3x3 matrix type used for rotations and inertia-tensor operations.
Definition matrix.hpp:27
double m[3][3]
Definition matrix.hpp:28
bool tryInverse(Matrix3 &out, double eps=std::numeric_limits< double >::epsilon()) const noexcept
Definition matrix.hpp:126
Vector3 operator*(const Vector3 &v) const noexcept
Definition matrix.hpp:90
double determinant() const noexcept
Definition matrix.hpp:118
constexpr Matrix3(double m00, double m01, double m02, double m10, double m11, double m12, double m20, double m21, double m22) noexcept
Definition matrix.hpp:34
bool operator!=(const Matrix3 &o) const noexcept
Definition matrix.hpp:183
constexpr Matrix3 operator*(double s) const noexcept
Definition matrix.hpp:78
const double * operator[](size_t i) const
Definition matrix.hpp:51
static constexpr Matrix3 identity() noexcept
Definition matrix.hpp:38
Matrix3 inverse() const noexcept
Definition matrix.hpp:154
static Matrix3 fromQuaternion(const Quaternion &q) noexcept
Definition matrix.hpp:164
constexpr Matrix3 operator-(const Matrix3 &o) const noexcept
Definition matrix.hpp:68
constexpr Matrix3() noexcept
Definition matrix.hpp:32
bool operator==(const Matrix3 &o) const noexcept
Definition matrix.hpp:174
constexpr Matrix3 operator+(const Matrix3 &o) const noexcept
Definition matrix.hpp:58
friend std::ostream & operator<<(std::ostream &os, const Matrix3 &mat)
Definition matrix.hpp:187
double * operator[](size_t i)
Definition matrix.hpp:46
Matrix3 transpose() const noexcept
Definition matrix.hpp:111
Matrix3 operator*(const Matrix3 &o) const noexcept
Definition matrix.hpp:98
static constexpr Matrix3 zero() noexcept
Definition matrix.hpp:40
Unit-quaternion rotation representation and rotation algebra helpers.
Definition quaternion.hpp:25
3D vector utility used throughout JSim physics.
Definition vector.hpp:22