1#![allow(clippy::derive_partial_eq_without_eq)]
3
4use std::ops::{Div, Mul, Neg};
5
6use crate::mul_add::FastMulAdd;
7
8#[derive(Debug, Clone, PartialEq)]
9#[must_use]
10pub struct RowVector<T>(T, T, T);
11
12impl<T: Copy> RowVector<T> {
13 pub const fn new(x: T, y: T, z: T) -> Self {
14 Self(x, y, z)
15 }
16
17 #[must_use]
18 pub const fn x(&self) -> T {
19 self.0
20 }
21 #[must_use]
22 pub const fn y(&self) -> T {
23 self.1
24 }
25 #[must_use]
26 pub const fn z(&self) -> T {
27 self.2
28 }
29
30 pub const fn values(self) -> [T; 3] {
31 let Self(x, y, z) = self;
32 [x, y, z]
33 }
34}
35
36impl<T> RowVector<T>
37where
38 T: Copy + FastMulAdd + Mul<T, Output = T> + Div<T, Output = T> + Neg<Output = T>,
39{
40 pub fn cross(&self, other: &Self) -> Self {
41 let Self(sx, sy, sz) = *self;
42 let Self(ox, oy, oz) = *other;
43
44 Self::new(
45 sy.fast_mul_add(oz, -(sz * oy)),
46 sz.fast_mul_add(ox, -(sx * oz)),
47 sx.fast_mul_add(oy, -(sy * ox)),
48 )
49 }
50
51 #[must_use]
52 pub fn dot(&self, other: &Self) -> T {
53 self.0
54 .fast_mul_add(other.0, self.1.fast_mul_add(other.1, self.2 * other.2))
55 }
56
57 pub fn scalar_div(&self, x: T) -> Self {
58 Self(self.0 / x, self.1 / x, self.2 / x)
59 }
60
61 pub fn component_mul(&self, other: &Self) -> Self {
62 Self(self.0 * other.0, self.1 * other.1, self.2 * other.2)
63 }
64}
65
66impl<T: Copy> From<[T; 3]> for RowVector<T> {
67 fn from(value: [T; 3]) -> Self {
68 let [x, y, z] = value;
69 Self::new(x, y, z)
70 }
71}
72
73#[derive(Debug, Clone, PartialEq)]
74#[must_use]
75pub struct ColVector<T>(T, T, T);
76
77impl<T: Copy> ColVector<T> {
78 pub const fn new(r: T, g: T, b: T) -> Self {
79 Self(r, g, b)
80 }
81
82 #[must_use]
83 pub const fn r(&self) -> T {
84 self.0
85 }
86 #[must_use]
87 pub const fn g(&self) -> T {
88 self.1
89 }
90 #[must_use]
91 pub const fn b(&self) -> T {
92 self.2
93 }
94
95 pub const fn transpose(self) -> RowVector<T> {
96 RowVector::new(self.0, self.1, self.2)
97 }
98
99 pub const fn values(self) -> [T; 3] {
100 let Self(r, g, b) = self;
101 [r, g, b]
102 }
103}
104
105impl<T: Copy> From<[T; 3]> for ColVector<T> {
106 fn from(value: [T; 3]) -> Self {
107 let [r, g, b] = value;
108 Self::new(r, g, b)
109 }
110}
111
112#[derive(Debug, Clone, PartialEq)]
113#[must_use]
114pub struct Matrix<T>(RowVector<T>, RowVector<T>, RowVector<T>);
115
116impl<T: Copy> Matrix<T> {
117 pub const fn new(r1: RowVector<T>, r2: RowVector<T>, r3: RowVector<T>) -> Self {
118 Self(r1, r2, r3)
119 }
120
121 pub const fn r1(&self) -> &RowVector<T> {
122 &self.0
123 }
124 pub const fn r2(&self) -> &RowVector<T> {
125 &self.1
126 }
127 pub const fn r3(&self) -> &RowVector<T> {
128 &self.2
129 }
130
131 pub const fn transpose(self) -> Self {
132 let Self(r1, r2, r3) = self;
133
134 let RowVector(s11, s12, s13) = r1;
135 let RowVector(s21, s22, s23) = r2;
136 let RowVector(s31, s32, s33) = r3;
137
138 Self::new(
139 RowVector::new(s11, s21, s31),
140 RowVector::new(s12, s22, s32),
141 RowVector::new(s13, s23, s33),
142 )
143 }
144}
145
146impl Matrix<f32> {
147 pub const fn identity() -> Self {
148 Self::new(
149 RowVector::new(1.0, 0.0, 0.0),
150 RowVector::new(0.0, 1.0, 0.0),
151 RowVector::new(0.0, 0.0, 1.0),
152 )
153 }
154}
155
156impl Matrix<f64> {
157 pub const fn identity() -> Self {
158 Self::new(
159 RowVector::new(1.0, 0.0, 0.0),
160 RowVector::new(0.0, 1.0, 0.0),
161 RowVector::new(0.0, 0.0, 1.0),
162 )
163 }
164}
165
166impl<T> Matrix<T>
167where
168 T: Copy + FastMulAdd + Mul<T, Output = T> + Div<T, Output = T> + Neg<Output = T>,
169{
170 pub fn scalar_div(&self, x: T) -> Self {
171 Self(
172 self.0.scalar_div(x),
173 self.1.scalar_div(x),
174 self.2.scalar_div(x),
175 )
176 }
177
178 pub fn invert(&self) -> Self {
180 let Self(ref r1, ref r2, ref r3) = *self;
182
183 let RowVector(s11, s12, s13) = *r1;
184 let RowVector(s21, s22, s23) = *r2;
185 let RowVector(s31, s32, s33) = *r3;
186
187 let minor_11 = s22.fast_mul_add(s33, -(s32 * s23));
188 let minor_12 = s21.fast_mul_add(s33, -(s31 * s23));
189 let minor_13 = s21.fast_mul_add(s32, -(s31 * s22));
190
191 let minor_21 = s12.fast_mul_add(s33, -(s32 * s13));
192 let minor_22 = s11.fast_mul_add(s33, -(s31 * s13));
193 let minor_23 = s11.fast_mul_add(s32, -(s31 * s12));
194
195 let minor_31 = s12.fast_mul_add(s23, -(s22 * s13));
196 let minor_32 = s11.fast_mul_add(s23, -(s21 * s13));
197 let minor_33 = s11.fast_mul_add(s22, -(s21 * s12));
198
199 let determinant =
200 s11.fast_mul_add(minor_11, -s12.fast_mul_add(minor_12, -(s13 * minor_13)));
201
202 Self::new(
203 RowVector::new(minor_11, -minor_12, minor_13),
204 RowVector::new(-minor_21, minor_22, -minor_23),
205 RowVector::new(minor_31, -minor_32, minor_33),
206 )
207 .transpose()
208 .scalar_div(determinant)
209 }
210
211 pub fn mul_vec(&self, rhs: &ColVector<T>) -> ColVector<T> {
212 let Self(ref r1, ref r2, ref r3) = *self;
213
214 ColVector::new(
215 r1.0.fast_mul_add(rhs.0, r1.1.fast_mul_add(rhs.1, r1.2 * rhs.2)),
216 r2.0.fast_mul_add(rhs.0, r2.1.fast_mul_add(rhs.1, r2.2 * rhs.2)),
217 r3.0.fast_mul_add(rhs.0, r3.1.fast_mul_add(rhs.1, r3.2 * rhs.2)),
218 )
219 }
220
221 pub fn mul_mat(&self, rhs: Self) -> Self {
222 let Self(ref r1, ref r2, ref r3) = *self;
223 let Self(o1, o2, o3) = rhs;
224
225 Self::new(
226 RowVector::new(
227 r1.0.fast_mul_add(o1.0, r1.1.fast_mul_add(o2.0, r1.2 * o3.0)),
228 r1.0.fast_mul_add(o1.1, r1.1.fast_mul_add(o2.1, r1.2 * o3.1)),
229 r1.0.fast_mul_add(o1.2, r1.1.fast_mul_add(o2.2, r1.2 * o3.2)),
230 ),
231 RowVector::new(
232 r2.0.fast_mul_add(o1.0, r2.1.fast_mul_add(o2.0, r2.2 * o3.0)),
233 r2.0.fast_mul_add(o1.1, r2.1.fast_mul_add(o2.1, r2.2 * o3.1)),
234 r2.0.fast_mul_add(o1.2, r2.1.fast_mul_add(o2.2, r2.2 * o3.2)),
235 ),
236 RowVector::new(
237 r3.0.fast_mul_add(o1.0, r3.1.fast_mul_add(o2.0, r3.2 * o3.0)),
238 r3.0.fast_mul_add(o1.1, r3.1.fast_mul_add(o2.1, r3.2 * o3.1)),
239 r3.0.fast_mul_add(o1.2, r3.1.fast_mul_add(o2.2, r3.2 * o3.2)),
240 ),
241 )
242 }
243
244 #[must_use]
245 pub fn mul_arr(&self, rhs: [T; 3]) -> [T; 3] {
246 let Self(ref r1, ref r2, ref r3) = *self;
247
248 [
249 r1.0.fast_mul_add(rhs[0], r1.1.fast_mul_add(rhs[1], r1.2 * rhs[2])),
250 r2.0.fast_mul_add(rhs[0], r2.1.fast_mul_add(rhs[1], r2.2 * rhs[2])),
251 r3.0.fast_mul_add(rhs[0], r3.1.fast_mul_add(rhs[1], r3.2 * rhs[2])),
252 ]
253 }
254
255 pub const fn values(self) -> [[T; 3]; 3] {
256 [self.0.values(), self.1.values(), self.2.values()]
257 }
258}