1#![allow(dead_code)]
2
3use std::{
4 fmt::Display,
5 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
6};
7
8use crate::algebra::{vec2f, Mat2d, Mat3f, Mat4f, Vec2f};
9
10#[derive(Clone, Copy, PartialEq, Debug)]
11pub struct Mat2f {
12 x_axis: Vec2f,
13 y_axis: Vec2f,
14}
15
16pub fn mat2f(m00: f32, m01: f32, m10: f32, m11: f32) -> Mat2f {
17 Mat2f::from_array([m00, m01, m10, m11])
18}
19
20impl Display for Mat2f {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 write!(
23 f,
24 "Mat2f({}, {} | {}, {})",
25 self.x_axis.x(),
26 self.x_axis.y(),
27 self.y_axis.x(),
28 self.y_axis.y()
29 )
30 }
31}
32
33impl Default for Mat2f {
34 fn default() -> Self {
35 Self {
36 x_axis: Vec2f::default(),
37 y_axis: Vec2f::default(),
38 }
39 }
40}
41
42impl Add<Mat2f> for Mat2f {
43 type Output = Mat2f;
44
45 fn add(self, rhs: Mat2f) -> Self::Output {
46 Mat2f::new(self.x_axis + rhs.x_axis, self.y_axis + rhs.y_axis)
47 }
48}
49
50impl Add<f32> for Mat2f {
51 type Output = Mat2f;
52
53 fn add(self, rhs: f32) -> Self::Output {
54 Mat2f::new(self.x_axis + rhs, self.y_axis + rhs)
55 }
56}
57
58impl Add<Mat2f> for f32 {
59 type Output = Mat2f;
60
61 fn add(self, rhs: Mat2f) -> Self::Output {
62 Mat2f::new(self + rhs.x_axis, self + rhs.y_axis)
63 }
64}
65
66impl AddAssign<Mat2f> for Mat2f {
67 fn add_assign(&mut self, rhs: Mat2f) {
68 *self = *self + rhs;
69 }
70}
71
72impl AddAssign<f32> for Mat2f {
73 fn add_assign(&mut self, rhs: f32) {
74 *self = *self + rhs;
75 }
76}
77
78impl Sub<Mat2f> for Mat2f {
79 type Output = Mat2f;
80
81 fn sub(self, rhs: Mat2f) -> Self::Output {
82 Mat2f::new(self.x_axis - rhs.x_axis, self.y_axis - rhs.y_axis)
83 }
84}
85
86impl Sub<f32> for Mat2f {
87 type Output = Mat2f;
88
89 fn sub(self, rhs: f32) -> Self::Output {
90 Mat2f::new(self.x_axis - rhs, self.y_axis - rhs)
91 }
92}
93
94impl Sub<Mat2f> for f32 {
95 type Output = Mat2f;
96
97 fn sub(self, rhs: Mat2f) -> Self::Output {
98 Mat2f::new(self - rhs.x_axis, self - rhs.y_axis)
99 }
100}
101
102impl SubAssign<Mat2f> for Mat2f {
103 fn sub_assign(&mut self, rhs: Mat2f) {
104 *self = *self - rhs;
105 }
106}
107
108impl SubAssign<f32> for Mat2f {
109 fn sub_assign(&mut self, rhs: f32) {
110 *self = *self - rhs;
111 }
112}
113
114impl Mul<Mat2f> for Mat2f {
115 type Output = Mat2f;
116
117 fn mul(self, rhs: Mat2f) -> Self::Output {
118 let m00 = self.x_axis.dot(vec2f(rhs[0][0], rhs[1][0]));
119 let m01 = self.x_axis.dot(vec2f(rhs[0][1], rhs[1][1]));
120 let m10 = self.y_axis.dot(vec2f(rhs[0][0], rhs[1][0]));
121 let m11 = self.y_axis.dot(vec2f(rhs[0][1], rhs[1][1]));
122 Mat2f::new(vec2f(m00, m01), vec2f(m10, m11))
123 }
124}
125
126impl Mul<Vec2f> for Mat2f {
127 type Output = Vec2f;
128
129 fn mul(self, rhs: Vec2f) -> Self::Output {
130 let v0 = self.x_axis.dot(rhs);
131 let v1 = self.y_axis.dot(rhs);
132 vec2f(v0, v1)
133 }
134}
135
136impl Mul<f32> for Mat2f {
137 type Output = Mat2f;
138
139 fn mul(self, rhs: f32) -> Self::Output {
140 Mat2f::new(self.x_axis * rhs, self.y_axis * rhs)
141 }
142}
143
144impl Mul<Mat2f> for f32 {
145 type Output = Mat2f;
146
147 fn mul(self, rhs: Mat2f) -> Self::Output {
148 Mat2f::new(self * rhs.x_axis, self * rhs.y_axis)
149 }
150}
151
152impl MulAssign<Mat2f> for Mat2f {
153 fn mul_assign(&mut self, rhs: Mat2f) {
154 *self = *self * rhs;
155 }
156}
157
158impl MulAssign<f32> for Mat2f {
159 fn mul_assign(&mut self, rhs: f32) {
160 *self = *self * rhs;
161 }
162}
163
164impl Div<f32> for Mat2f {
165 type Output = Mat2f;
166
167 fn div(self, rhs: f32) -> Self::Output {
168 Mat2f::new(self.x_axis / rhs, self.y_axis / rhs)
169 }
170}
171
172impl DivAssign<f32> for Mat2f {
173 fn div_assign(&mut self, rhs: f32) {
174 *self = *self / rhs;
175 }
176}
177
178impl Index<usize> for Mat2f {
179 type Output = Vec2f;
180
181 fn index(&self, index: usize) -> &Self::Output {
182 match index {
183 0 => &self.x_axis,
184 1 => &self.y_axis,
185 _ => panic!("`rmath::algebra::Mat2f::index`: index out of bounds."),
186 }
187 }
188}
189
190impl IndexMut<usize> for Mat2f {
191 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
192 match index {
193 0 => &mut self.x_axis,
194 1 => &mut self.y_axis,
195 _ => panic!("`rmath::algebra::Mat2f::index_mut`: index out of bounds."),
196 }
197 }
198}
199
200impl Mat2f {
201 pub fn new(x_axis: Vec2f, y_axis: Vec2f) -> Self {
202 Self { x_axis, y_axis }
203 }
204
205 pub fn zero() -> Self {
206 Self::new(vec2f(0.0, 0.0), vec2f(0.0, 0.0))
207 }
208
209 pub fn identity() -> Self {
210 Self::new(vec2f(1.0, 0.0), vec2f(0.0, 1.0))
211 }
212}
213
214impl Mat2f {
215 pub fn col(&self, index: usize) -> Vec2f {
216 match index {
217 0 => vec2f(self[0][0], self[1][0]),
218 1 => vec2f(self[0][1], self[1][1]),
219 _ => panic!("`rmath::algebra::Mat2f::col`: index out of bounds."),
220 }
221 }
222
223 pub fn row(&self, index: usize) -> Vec2f {
224 match index {
225 0 => self.x_axis,
226 1 => self.y_axis,
227 _ => panic!("`rmath::algebra::Mat2f::row`: index out of bounds."),
228 }
229 }
230
231 pub fn is_nan(&self) -> bool {
232 self.x_axis.is_nan() || self.y_axis.is_nan()
233 }
234
235 pub fn is_infinite(&self) -> bool {
236 self.x_axis.is_infinite() || self.y_axis.is_infinite()
237 }
238
239 pub fn is_finite(&self) -> bool {
240 self.x_axis.is_finite() && self.y_axis.is_finite()
241 }
242
243 pub fn transpose(&self) -> Self {
244 let (m00, m01) = self.x_axis.to_tuple();
245 let (m10, m11) = self.y_axis.to_tuple();
246 Self::new(vec2f(m00, m10), vec2f(m01, m11))
247 }
248
249 pub fn determinant(&self) -> f32 {
250 let (m00, m01) = self.x_axis.to_tuple();
251 let (m10, m11) = self.y_axis.to_tuple();
252 m00 * m11 - m01 * m10
253 }
254
255 pub fn inverse(&self) -> Self {
256 let det = self.determinant();
257 ruby_assert!(!(det.abs() < f32::EPSILON));
258
259 let inv_det = det.recip();
260 let a00 = self[1][1];
261 let a01 = -self[1][0];
262 let a10 = -self[0][1];
263 let a11 = self[0][0];
264
265 Self::new(vec2f(a00, a10), vec2f(a01, a11)).mul(inv_det)
266 }
267
268 pub fn try_inverse(&self) -> Option<Self> {
269 let det = self.determinant();
270 if det.abs() < f32::EPSILON {
271 return None;
272 }
273
274 let inv_det = det.recip();
275 let a00 = self[1][1];
276 let a01 = -self[1][0];
277 let a10 = -self[0][1];
278 let a11 = self[0][0];
279
280 Some(Self::new(vec2f(a00, a10), vec2f(a01, a11)).mul(inv_det))
281 }
282}
283
284impl From<Mat3f> for Mat2f {
285 fn from(m: Mat3f) -> Self {
286 mat2f(m[0][0], m[0][1], m[1][0], m[1][1])
287 }
288}
289
290impl From<Mat4f> for Mat2f {
291 fn from(m: Mat4f) -> Self {
292 mat2f(m[0][0], m[0][1], m[1][0], m[1][1])
293 }
294}
295
296impl Mat2f {
297 pub fn from_array(m: [f32; 4]) -> Self {
298 Self::new(vec2f(m[0], m[1]), vec2f(m[2], m[3]))
299 }
300
301 pub fn from_array_2d(m: [[f32; 2]; 2]) -> Self {
302 Self::new(vec2f(m[0][0], m[0][1]), vec2f(m[1][0], m[1][1]))
303 }
304
305 pub fn from_diagonal(diagonal: Vec2f) -> Self {
306 Self::new(vec2f(diagonal.x(), 0.0), vec2f(0.0, diagonal.y()))
307 }
308}
309
310impl Mat2f {
311 pub fn to_array(self) -> [f32; 4] {
312 [self[0][0], self[0][1], self[1][0], self[1][1]]
313 }
314
315 pub fn to_array_2d(self) -> [[f32; 2]; 2] {
316 [[self[0][0], self[0][1]], [self[1][0], self[1][1]]]
317 }
318
319 pub fn to_mat3f(self) -> Mat3f {
320 Mat3f::from(self)
321 }
322
323 pub fn to_mat4f(self) -> Mat4f {
324 Mat4f::from(self)
325 }
326
327 pub fn to_mat2d(self) -> Mat2d {
328 Mat2d::new(self.x_axis.to_vec2d(), self.y_axis.to_vec2d())
329 }
330}