sandbox
Loading...
Searching...
No Matches
matrix3x3.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_MATH_MATRIX3X3_HPP_
3#define LIBSBX_MATH_MATRIX3X3_HPP_
4
5#include <array>
6#include <cstddef>
7#include <cmath>
8#include <cinttypes>
9#include <concepts>
10#include <fstream>
11#include <ostream>
12#include <type_traits>
13
14#include <fmt/format.h>
15
17#include <libsbx/math/vector3.hpp>
18#include <libsbx/math/vector4.hpp>
20#include <libsbx/math/angle.hpp>
21#include <libsbx/math/traits.hpp>
22
23namespace sbx::math {
24
25template<scalar Type>
26class basic_matrix3x3 : public basic_matrix<3u, 3u, Type> {
27
29
30 template<scalar Other>
32
33 inline static constexpr auto x_axis = std::size_t{0u};
34 inline static constexpr auto y_axis = std::size_t{1u};
35 inline static constexpr auto z_axis = std::size_t{2u};
36
37public:
38
39 using value_type = base_type::value_type;
40 using reference = base_type::reference;
41 using const_reference = base_type::const_reference;
42 using size_type = base_type::size_type;
44
45 inline static constexpr basic_matrix3x3 identity{base_type::identity()};
46 inline static constexpr basic_matrix3x3 zero{base_type{value_type{0}}};
47
48 using base_type::base_type;
49
50 constexpr basic_matrix3x3(const base_type& base) noexcept;
51
52 template<typename Column0, typename Column1, typename Column2>
53 constexpr basic_matrix3x3(
54 Column0&& column0,
55 Column1&& column1,
56 Column2&& column2
57 ) noexcept;
58
59 template<scalar Other>
60 constexpr basic_matrix3x3(
61 Other x0, Other x1, Other x2,
62 Other y0, Other y1, Other y2,
63 Other z0, Other z1, Other z2
64 ) noexcept;
65
66 template<scalar Other>
67 constexpr basic_matrix3x3(const Other v00, const Other v11, const Other v22) noexcept;
68
69 template<scalar Other>
70 constexpr basic_matrix3x3(const Other diagonal) noexcept;
71
72 // -- Static member functions --
73
74 [[nodiscard]] constexpr static auto inverted(const basic_matrix3x3& matrix) -> basic_matrix3x3 {
75 const auto m00 = matrix[0][0];
76 const auto m01 = matrix[0][1];
77 const auto m02 = matrix[0][2];
78
79 const auto m10 = matrix[1][0];
80 const auto m11 = matrix[1][1];
81 const auto m12 = matrix[1][2];
82
83 const auto m20 = matrix[2][0];
84 const auto m21 = matrix[2][1];
85 const auto m22 = matrix[2][2];
86
87 const auto determinant = m00 * (m11 * m22 - m21 * m12) - m10 * (m01 * m22 - m21 * m02) + m20 * (m01 * m12 - m11 * m02);
88
89 if (comparision_traits<value_type>::equal(determinant, 0)) {
90 return identity;
91 }
92
93 const auto inv_determinant = value_type{1} / determinant;
94
95 auto result = basic_matrix3x3{};
96
97 result[0][0] = (m11 * m22 - m21 * m12) * inv_determinant;
98 result[0][1] = (m21 * m02 - m01 * m22) * inv_determinant;
99 result[0][2] = (m01 * m12 - m11 * m02) * inv_determinant;
100
101 result[1][0] = (m20 * m12 - m10 * m22) * inv_determinant;
102 result[1][1] = (m00 * m22 - m20 * m02) * inv_determinant;
103 result[1][2] = (m10 * m02 - m00 * m12) * inv_determinant;
104
105 result[2][0] = (m10 * m21 - m20 * m11) * inv_determinant;
106 result[2][1] = (m20 * m01 - m00 * m21) * inv_determinant;
107 result[2][2] = (m00 * m11 - m10 * m01) * inv_determinant;
108
109 return result;
110 }
111
112 [[nodiscard]] constexpr static auto transposed(const basic_matrix3x3& matrix) noexcept -> basic_matrix3x3 {
113 auto result = basic_matrix3x3<value_type>{};
114
115 result[0][0] = matrix[0][0];
116 result[0][1] = matrix[1][0];
117 result[0][2] = matrix[2][0];
118
119 result[1][0] = matrix[0][1];
120 result[1][1] = matrix[1][1];
121 result[1][2] = matrix[2][1];
122
123 result[2][0] = matrix[0][2];
124 result[2][1] = matrix[1][2];
125 result[2][2] = matrix[2][2];
126
127 return result;
128 }
129
130 [[nodiscard]] constexpr static auto ortho_normal(const basic_matrix3x3& matrix) -> basic_matrix3x3 {
131 auto x = basic_vector3<value_type>{matrix[x_axis]};
132 auto y = basic_vector3<value_type>{matrix[y_axis]};
133 auto z = basic_vector3<value_type>{matrix[z_axis]};
134
135 const auto x_length = x.length();
136 const auto y_length = y.length();
137 const auto z_length = z.length();
138
139 if (x_length < math::epsilon_v<value_type> || y_length < math::epsilon_v<value_type> || z_length < math::epsilon_v<value_type>) {
141 }
142
143 x /= x_length;
144 y /= y_length;
145 z /= z_length;
146
148 if (x_length >= y_length && x_length >= z_length) {
149 x = -x;
150 } else if (y_length >= z_length) {
151 y = -y;
152 } else {
153 z = -z;
154 }
155 }
156
157 x = math::vector3::normalized(x);
158 y = math::vector3::normalized(y - x * math::vector3::dot(x, y));
159 z = math::vector3::cross(x, y);
160
161 return basic_matrix3x3<value_type>{x, y, z};
162 }
163
164 [[nodiscard]] constexpr static auto abs(const basic_matrix3x3& matrix) noexcept -> basic_matrix3x3 {
165 return basic_matrix3x3{
166 column_type::abs(matrix[0]),
167 column_type::abs(matrix[1]),
168 column_type::abs(matrix[2])
169 };
170 }
171
172 // [[nodiscard]] constexpr static auto inverted(const basic_matrix3x3& matrix) -> basic_matrix3x3;
173
174 // [[nodiscard]] constexpr static auto perspective(const basic_angle<value_type>& fov, const value_type aspect, const value_type near, const value_type far) noexcept -> basic_matrix3x3;
175
176 // [[nodiscard]] constexpr static auto translated(const basic_matrix3x3& matrix, const basic_vector3<value_type>& vector) noexcept -> basic_matrix3x3;
177
178 // [[nodiscard]] constexpr static auto scaled(const basic_matrix3x3& matrix, const basic_vector3<value_type>& vector) noexcept -> basic_matrix3x3;
179
180 // [[nodiscard]] constexpr static auto rotated(const basic_matrix3x3& matrix, const basic_vector3<value_type>& axis, const basic_angle<value_type>& angle) noexcept -> basic_matrix3x3;
181
182 // [[nodiscard]] constexpr static auto rotation_from_euler_angles(const basic_vector3<value_type>& euler_angles) noexcept -> basic_matrix3x3;
183
184 constexpr auto operator[](size_type index) const noexcept -> const column_type&;
185
186 constexpr auto operator[](size_type index) noexcept -> column_type&;
187
188}; // class basic_matrix3x3
189
190// template<scalar Lhs, scalar Rhs>
191// [[nodiscard]] constexpr auto operator+(basic_matrix3x3<Lhs> lhs, const basic_matrix3x3<Rhs>& rhs) noexcept -> basic_matrix3x3<Lhs>;
192
193// template<scalar Lhs, scalar Rhs>
194// [[nodiscard]] constexpr auto operator-(basic_matrix3x3<Lhs> lhs, const basic_matrix3x3<Rhs>& rhs) noexcept -> basic_matrix3x3<Lhs>;
195
196// template<scalar Lhs, scalar Rhs>
197// [[nodiscard]] constexpr auto operator*(basic_matrix3x3<Lhs> lhs, Rhs scalar) noexcept -> basic_matrix3x3<Lhs>;
198
199template<scalar Lhs, scalar Rhs>
200[[nodiscard]] constexpr auto operator*(basic_matrix3x3<Lhs> lhs, const basic_vector3<Rhs>& rhs) noexcept -> basic_vector3<Lhs>;
201
202template<scalar Lhs, scalar Rhs>
203[[nodiscard]] constexpr auto operator*(basic_matrix3x3<Lhs> lhs, const basic_matrix3x3<Rhs>& rhs) noexcept -> basic_matrix3x3<Lhs>;
204
205// template<scalar Lhs, scalar Rhs>
206// [[nodiscard]] constexpr auto operator/(basic_matrix3x3<Lhs> lhs, Rhs scalar) noexcept -> basic_matrix3x3<Lhs>;
207
209
211
212using matrix3x3 = matrix3x3f;
213
214} // namespace sbx::math
215
216template<sbx::math::scalar Type>
217struct fmt::formatter<sbx::math::basic_matrix3x3<Type>> {
218
219 template<typename ParseContext>
220 constexpr auto parse(ParseContext& context) const -> decltype(context.begin()) {
221 return context.begin();
222 }
223
224 template<typename FormatContext>
225 auto format(const sbx::math::basic_matrix3x3<Type>& matrix, FormatContext& context) const -> decltype(context.out()) {
226 if constexpr (sbx::math::is_floating_point_v<Type>) {
227 return fmt::format_to(context.out(),
228 "\n{:.2f}, {:.2f}, {:.2f}\n{:.2f}, {:.2f}, {:.2f}\n{:.2f}, {:.2f}, {:.2f}",
229 matrix[0][0], matrix[1][0], matrix[2][0],
230 matrix[0][1], matrix[1][1], matrix[2][1],
231 matrix[0][2], matrix[1][2], matrix[2][2]
232 );
233 } else {
234 return fmt::format_to(context.out(),
235 "\n{}, {}, {}\n{}, {}, {}\n{}, {}, {}\n{}, {}, {}",
236 matrix[0][0], matrix[1][0], matrix[2][0],
237 matrix[0][1], matrix[1][1], matrix[2][1],
238 matrix[0][2], matrix[1][2], matrix[2][2]
239 );
240 }
241 }
242
243}; // struct fmt::formatter
244
245#include <libsbx/math/matrix3x3.ipp>
246
247#endif // LIBSBX_MATH_MATRIX3X3_HPP_
Angle types and utilities.
constexpr auto operator*(basic_degree< Type > lhs, const Other rhs) noexcept -> basic_degree< Type >
Multiplies a degree value by a scalar factor.
Definition: angle.ipp:105
Definition: matrix3x3.hpp:26
Fixed-size column-major matrix.
Definition: matrix.hpp:48
static constexpr auto identity(const value_type value=static_cast< value_type >(1)) noexcept -> basic_matrix
Constructs an identity matrix.
Definition: matrix.ipp:113
Definition: vector3.hpp:23
static constexpr auto abs(const basic_vector< Size, Lhs > &vector) noexcept -> basic_vector
Returns the component-wise absolute value of a vector.
Definition: vector.ipp:71
Core numeric concepts and type traits.
Generic fixed-size matrix type.
Definition: traits.hpp:11