1use super::*;
2
3
4pub type Matrix1<T> = SquareMatrix<T,1>;
6pub type Matrix2<T> = SquareMatrix<T,2>;
8pub type Matrix3<T> = SquareMatrix<T,3>;
10pub type Matrix4<T> = SquareMatrix<T,4>;
12
13pub type Mat<const ROW : usize, const COL : usize> = Matrix<float,ROW,COL>;
14pub type Mat1 = Mat<1,1>;
16pub type Mat2 = Mat<2,2>;
18pub type Mat3 = Mat<3,3>;
20pub type Mat4 = Mat<4,4>;
22
23pub type MatP<const COL : usize> = SquareMatrix<int,COL>;
24pub type Mat1P = MatP<1>;
26pub type Mat2P = MatP<2>;
28pub type Mat3P = MatP<3>;
30pub type Mat4P = MatP<4>;
32
33
34
35
36pub type SquareMatrix<T, const N : usize> = Matrix<T, N, N>;
38
39#[repr(C)]
45#[derive(PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(transparent))]
47#[cfg_attr(feature = "hexga_io", derive(Save, Load))]
48pub struct Matrix<T, const ROW : usize, const COL : usize>
49{
50 columns : Vector<Vector<T, ROW>,COL>,
51}
52
53
54impl<T, const ROW : usize, const COL : usize> Deref for Matrix<T, ROW, COL>
55{
56 type Target=Vector<Vector<T, ROW>,COL>;
57 fn deref(&self) -> &Self::Target { &self.columns }
58}
59
60impl<T, const ROW : usize, const COL : usize> DerefMut for Matrix<T, ROW, COL>
61{
62 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.columns }
63}
64
65impl<T, const ROW : usize, const COL : usize> Matrix<T, ROW, COL>
66{
67 fn _fmt(&self, f: &mut Formatter<'_>, d : impl Fn(&T, &mut Formatter<'_>) -> FmtResult) -> FmtResult
68 {
69 const SEP :&'static str = " ";
70
71 let mut strings: Vec<String> = Vec::with_capacity(ROW * COL);
72
73 let mut width = 0;
74
75 for c in 0..COL
76 {
77 for r in 0..ROW
78 {
79 strings.push(___());
80 let mut tmp_f = std::fmt::Formatter::new(strings.last_mut().unwrap(), ___());
81 d(&self[c][r], &mut tmp_f)?;
82 width = max(width, strings.last().unwrap().len());
83 }
84 }
85
86 for c in 0..COL
87 {
88 for r in 0..ROW
89 {
90 let idx = r * COL + c;
91 write!(f, "{:>width$}{}", strings[idx], SEP, width = width)?;
92 }
93 writeln!(f)?;
94 }
95 Ok(())
96 }
97}
98
99use std::fmt;
100impl<T, const ROW : usize, const COL : usize> fmt::Display for Matrix<T, ROW, COL> where T: fmt::Display { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
101impl<T, const ROW : usize, const COL : usize> fmt::Debug for Matrix<T, ROW, COL> where T: fmt::Debug { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
102impl<T, const ROW : usize, const COL : usize> fmt::Octal for Matrix<T, ROW, COL> where T: fmt::Octal { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
103impl<T, const ROW : usize, const COL : usize> fmt::Binary for Matrix<T, ROW, COL> where T: fmt::Binary { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
104impl<T, const ROW : usize, const COL : usize> fmt::LowerHex for Matrix<T, ROW, COL> where T: fmt::LowerHex { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
105impl<T, const ROW : usize, const COL : usize> fmt::UpperHex for Matrix<T, ROW, COL> where T: fmt::UpperHex { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
106impl<T, const ROW : usize, const COL : usize> fmt::LowerExp for Matrix<T, ROW, COL> where T: fmt::LowerExp { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
107impl<T, const ROW : usize, const COL : usize> fmt::UpperExp for Matrix<T, ROW, COL> where T: fmt::UpperExp { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
108impl<T, const ROW : usize, const COL : usize> fmt::Pointer for Matrix<T, ROW, COL> where T: fmt::Pointer { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { self._fmt(f, T::fmt) } }
109
110impl<T, const ROW : usize, const COL : usize> Default for Matrix<T,ROW,COL> where Vector<Vector<T, ROW>,COL> : Default
111{
112 fn default() -> Self {
113 Self { columns: ___() }
114 }
115}
116
117impl<T, const ROW : usize> Matrix<T,ROW,1>
118{
119 pub const fn from_vector(vector : Vector<T, ROW>) -> Self
121 {
122 Self::from_col(Vector::from_array([vector]))
123 }
124}
125
126impl<T, const ROW : usize> From<Vector<T, ROW>> for Matrix<T,ROW,1>
127{
128 fn from(value: Vector<T, ROW>) -> Self {
129 Self::from_vector(value)
130 }
131}
132impl<T, const ROW : usize> From<Matrix<T,ROW,1>> for Vector<T, ROW> where Vector<T,ROW> : Default
133{
134 fn from(mut value: Matrix<T,ROW,1>) -> Self
135 {
136 std::mem::take(&mut value.columns[0])
137 }
138}
139
140impl<T, const ROW : usize, const COL : usize> Matrix<T,ROW,COL>
141{
142 pub fn from_fn<F>(mut column_then_row : F) -> Self where F : FnMut(Point2) -> T
144 {
145 Self::from_col_array(std::array::from_fn(|column| std::array::from_fn(|row| column_then_row(point2(column as _,row as _)))))
146 }
147
148 pub fn from_col_fn<F>(mut column_then_row : F) -> Self where F : FnMut(usize, usize) -> T
149 {
150 Self::from_col_array(std::array::from_fn(|column| std::array::from_fn(|row| column_then_row(column,row))))
151 }
152
153 pub fn from_row_fn<F>(mut row_then_column : F) -> Self where F : FnMut(usize, usize) -> T
154 {
155 Self::from_col_array(std::array::from_fn(|column| std::array::from_fn(|row| row_then_column(row,column))))
156 }
157
158 pub const fn from_col(columns : Vector<Vector<T, ROW>,COL>) -> Self { Self { columns }}
159 pub fn from_col_array(columns : [[T;ROW];COL]) -> Self
160 {
161 Self
162 {
163 columns : Vector::from_array(columns.map(|array| Vector::from_array(array)))
164 }
165 }
166
167 pub fn from_row(rows : Vector<Vector<T, COL>,ROW>) -> Self where T: Copy
168 {
169 Matrix::from_col(rows).transpose()
170 }
171 pub fn from_row_array(rows : [[T;COL];ROW]) -> Self where T: Copy
172 {
173 Self::from_row(Vector::from_array(rows.map(|array| Vector::from_array(array))))
174 }
175
176 pub fn col(&self) -> Vector<Vector<T, ROW>,COL> where T: Copy { self.columns }
177 pub fn row(&self) -> Vector<Vector<T, COL>,ROW> where T: Copy { self.transpose().columns }
178
179 pub fn iter_col(&self) -> impl Iterator<Item = Vector<T, ROW>> where Vector<Vector<T, ROW>,COL> : Copy, T : Copy { self.columns.into_iter()}
180 pub fn iter_row(&self) -> impl Iterator<Item = Vector<T, COL>> where Vector<Vector<T, ROW>,COL> : Copy, T : Copy { self.transpose().into_iter()}
181
182 pub fn transpose(&self) -> Matrix<T,COL,ROW> where T: Copy
198 {
199 Matrix::from_col(Vector::from_fn(|x| Vector::from_fn(|y| self[y][x])))
200 }
201}
202
203
204impl<T, const ROW : usize, const COL : usize> GetMatrix<T,ROW,COL> for Matrix<T,ROW,COL> where Self: Copy
205{
206 fn matrix(&self) -> Matrix<T,ROW,COL> {
207 *self
208 }
209}
210
211impl<T, const ROW : usize, const COL : usize> SetMatrix<T,ROW,COL> for Matrix<T,ROW,COL> where Self: Copy
212{
213 fn set_matrix(&mut self, matrix : Matrix<T,ROW,COL>) -> &mut Self {
214 *self = matrix; self
215 }
216}
217
218
219impl<T> SquareMatrix<T,2>
221 where
222 Self : Copy,
223 SquareMatrix<T, 2> : Mul<Vector<T, 2>, Output = Vector<T, 2>>,
224 Vector<T, 2> : Into< Vector<T, 1>>
225{
226 pub fn transform_relative(self, relative : Vector<T, 1>) -> Vector<T, 1> where T: Zero
227 {
228 self.transform(relative.with_y(T::ZERO)).into()
229 }
230
231 pub fn transform_position(self, position : Vector<T, 1>) -> Vector<T, 1> where T: One
232 {
233 self.transform(position.with_y(T::ONE)).into()
234 }
235}
236
237impl<T> SquareMatrix<T,3>
239 where
240 Self : Copy,
241 SquareMatrix<T, 3> : Mul<Vector<T, 3>, Output = Vector<T, 3>>,
242 Vector<T, 3> : Into< Vector<T, 2>>
243{
244 pub fn transform_relative(self, relative : Vector<T, 2>) -> Vector<T, 2> where T: Zero
245 {
246 self.transform(relative.with_z(T::ZERO)).into()
247 }
248
249 pub fn transform_position(self, position : Vector<T, 2>) -> Vector<T, 2> where T: One
250 {
251 self.transform(position.with_z(T::ONE)).into()
252 }
253}
254
255impl<T> SquareMatrix<T,4>
257 where
258 Self : Copy,
259 SquareMatrix<T, 4> : Mul<Vector<T, 4>, Output = Vector<T, 4>>,
260 Vector<T, 4> : Into< Vector<T, 3>>
261{
262 pub fn transform_relative(self, relative : Vector<T, 3>) -> Vector<T, 3> where T: Zero
263 {
264 self.transform(relative.with_w(T::ZERO)).into()
265 }
266
267 pub fn transform_position(self, position : Vector<T, 3>) -> Vector<T, 3> where T: One
268 {
269 self.transform(position.with_w(T::ONE)).into()
270 }
271}
272
273
274impl<T, const N : usize> SquareMatrix<T,N>
275 where
276 Self : Copy,
277 SquareMatrix<T, N>: Mul<Vector<T, N>, Output = Vector<T, N>>
278{
279 pub fn transform(self, value : Vector<T, N>) -> Vector<T, N>
294 {
295 self * value
296 }
297}
298
299
300
301
302impl<T, const ROW : usize, const COL : usize> Zero for Matrix<T,ROW,COL> where Vector<Vector<T,ROW>,COL> : Zero
303{
304 const ZERO : Self = Self::from_col(Vector::<Vector::<T, ROW>, COL>::ZERO);
305}
306
307impl<T, const N : usize> SquareMatrix<T,N> where T: One + Zero + Copy
308{
309 pub const IDENTITY : Self = Self::ONE;
311}
312
313
314impl<T, const N : usize> One for SquareMatrix<T,N> where T: One + Zero + Copy
315{
316 const ONE : Self =
317 {
318 let mut col = [[T::ZERO; N]; N];
319 let mut i = 0;
320 while i < N
321 {
322 col[i][i] = T::ONE;
323 i+=1;
324 }
325 Self::from_col(unsafe { std::mem::transmute_copy(&col) })
326 };
327}
328
329impl<T, const N : usize> MinusOne for SquareMatrix<T,N> where T: MinusOne + Zero + Copy
330{
331 const MINUS_ONE : Self =
332 {
333 let mut col = [[T::ZERO; N]; N];
334 let mut i = 0;
335 while i < N
336 {
337 col[i][i] = T::MINUS_ONE;
338 i+=1;
339 }
340 Self::from_col(unsafe { std::mem::transmute_copy(&col) })
341 };
342}
343
344impl<T, const N : usize> Half for SquareMatrix<T,N> where T: Half + Zero + Copy
345{
346 const HALF : Self =
347 {
348 let mut col = [[T::ZERO; N]; N];
349 let mut i = 0;
350 while i < N
351 {
352 col[i][i] = T::HALF;
353 i+=1;
354 }
355 Self::from_col(unsafe { std::mem::transmute_copy(&col) })
356 };
357}
358
359
360impl<T, const N : usize> SquareMatrix<T,N> where T: Copy
361{
362 pub fn diag(&self) -> Vector<T,N> { Vector::from_fn(|i| self[i][i]) }
364 pub fn set_diag(&mut self, diag: Vector<T,N>)
366 {
367 for i in 0..N
368 {
369 self[i][i] = diag[i];
370 }
371 }
372}
373
374map_on!(
375 (
376 (MinValue, MIN),
377 (MaxValue, MAX),
378 (NaNValue, NAN)
379 ),
380 (($trait_name : ident, $constant_name : ident)) =>
381 {
382 impl<T, const ROW : usize, const COL : usize> $trait_name for Matrix<T,ROW,COL> where T: $trait_name + Copy
383 {
384 const $constant_name : Self = Self::from_col(Vector::from_array([Vector::from_array([T::$constant_name; ROW]); COL]));
385 }
386 }
387);
388
389impl<T, const ROW : usize, const COL : usize> Add<Self> for Matrix<T,ROW,COL>
390 where
391 Vector<Vector<T, ROW>, COL> : Add<Vector<Vector<T, ROW>, COL>,Output = Vector<Vector<T, ROW>, COL>>
392{
393 type Output = Self;
394
395 fn add(self, rhs: Self) -> Self::Output
396 {
397 Self::from_col(self.columns.add(rhs.columns))
398 }
399}
400
401impl<T, const ROW : usize, const COL : usize> AddAssign<Self> for Matrix<T,ROW,COL>
402 where
403 Self : Add<Self,Output = Self> + Copy
404{
405 fn add_assign(&mut self, rhs: Self) {
406 *self = (*self).add(rhs);
407 }
408}
409
410
411impl<T, const ROW : usize, const COL : usize> Sub<Self> for Matrix<T,ROW,COL>
412 where
413 Vector<Vector<T, ROW>, COL> : Sub<Vector<Vector<T, ROW>, COL>,Output = Vector<Vector<T, ROW>, COL>>
414{
415 type Output = Self;
416
417 fn sub(self, rhs: Self) -> Self::Output
418 {
419 Self::from_col(self.columns.sub(rhs.columns))
420 }
421}
422
423impl<T, const ROW : usize, const COL : usize> SubAssign<Self> for Matrix<T,ROW,COL>
424 where
425 Self : Sub<Self,Output = Self> + Copy
426{
427 fn sub_assign(&mut self, rhs: Self) {
428 *self = (*self).sub(rhs);
429 }
430}
431
432
433impl<T, const ROW : usize, const COL : usize> Sum for Matrix<T,ROW,COL> where Self : Zero + Add<Self,Output = Self>
434{
435 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
436 iter.fold(Self::ZERO, Self::add)
437 }
438}
439
440impl<T, const COL : usize> Product for SquareMatrix<T,COL> where Self : One + Mul<Self,Output = Self>
441{
442 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
443 iter.fold(Self::ONE, Self::mul)
444 }
445}
446
447impl<T, const ROW : usize, const COL : usize, const COL2 : usize> Mul<Matrix<T,COL,COL2>> for Matrix<T,ROW,COL>
464 where
465 T : Numeric,
466{
467 type Output = Matrix<T, ROW, COL2>;
468
469 fn mul(self, rhs: Matrix<T,COL,COL2>) -> Self::Output
470 {
471 Matrix::from_col(Vector::from_fn(|c| Vector::from_fn(|r| (0..COL).map(|k| self[k][r] * rhs[c][k]).sum())))
474 }
475}
476
477
478impl<T, const ROW : usize, const COL : usize> Mul<Vector<T,COL>> for Matrix<T,ROW,COL>
479 where
480 T : Numeric,
481 Self : Mul<Matrix<T,COL,1>, Output = Matrix<T,ROW,1>>,
483 Vector<T,COL> : From<Matrix::<T,ROW,1>>
484{
485 type Output = Vector<T,COL>;
486
487 fn mul(self, rhs: Vector<T,COL>) -> Self::Output
488 {
489 let m : Matrix::<T,COL,1> = rhs.into();
490 let r = self * m;
491 r.into()
492 }
493}
494
495impl<T, const COL : usize> MulAssign<Self> for SquareMatrix<T,COL>
496 where
497 Self : Mul<Self,Output = Self> + Copy
498{
499 fn mul_assign(&mut self, rhs: Self) {
500 *self = *self * rhs;
501 }
502}
503
504impl<T, const ROW : usize, const COL : usize> Mul<T> for Matrix<T,ROW,COL> where T: Copy + Mul<T>
505{
506 type Output = Matrix<T::Output,ROW,COL>;
507
508 fn mul(self, rhs: T) -> Self::Output
509 {
510 Matrix::from_col(self.columns.map(|v| v.map(|i| i.mul(rhs))))
511 }
512}
513
514impl<T, const ROW : usize, const COL : usize> MulAssign<T> for Matrix<T,ROW,COL> where T: Copy + Mul<T,Output = T>
515{
516 fn mul_assign(&mut self, rhs: T) {
517 *self = (*self).mul(rhs);
518 }
519}
520
521impl<T, const ROW : usize, const COL : usize> Div<T> for Matrix<T,ROW,COL> where T: Copy + Div<T>
522{
523 type Output = Matrix<T::Output,ROW,COL>;
524
525 fn div(self, rhs: T) -> Self::Output
526 {
527 Matrix::from_col(self.columns.map(|v| v.map(|i| i.div(rhs))))
528 }
529}
530
531impl<T, const ROW : usize, const COL : usize> DivAssign<T> for Matrix<T,ROW,COL> where T: Copy + Div<T,Output = T>
532{
533 fn div_assign(&mut self, rhs: T) {
534 *self = (*self).div(rhs);
535 }
536}
537
538
539impl<T, const ROW : usize, const COL : usize> Map for Matrix<T,ROW,COL>
540{
541 type Item=T;
542 fn map_intern<F>(self, f: F) -> Self where F: FnMut(Self::Item) -> Self::Item
543 {
544 self.map(f)
545 }
546
547 fn map_with_intern<F>(self, other: Self, f: F) -> Self where F: FnMut(Self::Item, Self::Item) -> Self::Item {
548 self.map_with(other, f)
549 }
550}
551impl<T, const ROW : usize, const COL : usize> MapGeneric for Matrix<T,ROW,COL>
552{
553 type WithType<R> = Matrix<R,ROW,COL>;
554
555 fn map<R,F>(self, mut f: F) -> Self::WithType<R> where F: FnMut(Self::Item) -> R {
556 let mut it = self.columns.into_iter();
557 let cols = std::array::from_fn(|_| MapGeneric::map(it.next().unwrap(), &mut f));
558 Self::WithType::<R>::from_col(Vector::from_array(cols))
559 }
560
561 fn map_with<R, Item2, F>(self, other: Self::WithType<Item2>, mut f : F) -> Self::WithType<R> where F: FnMut(Self::Item, Item2) -> R {
562 let mut it1 = self.columns.into_iter();
563 let mut it2 = other.columns.into_iter();
564 let cols = std::array::from_fn(|_| MapGeneric::map_with(it1.next().unwrap(), it2.next().unwrap(), &mut f));
565 Self::WithType::<R>::from_col(Vector::from_array(cols))
566 }
567}
568
569
570
571impl<T, const N: usize> SquareMatrix<T, N>
572where
573 T: Float,
574{
575 pub fn inverse(mut self) -> Option<Self>
593 {
594 let mut augmented = Self::IDENTITY;
595
596 for i in 0..N
597 {
598 if self[i][i] == T::ZERO { return None; }
599
600 let pivot = self[i][i];
601
602 for j in 0..N
603 {
604 self[i][j] /= pivot;
605 augmented[i][j] /= pivot;
606 }
607
608 for k in (i + 1)..N
609 {
610 let factor = self[k][i];
611 for j in 0..N
612 {
613 self[k][j] = self[k][j] - factor * self[i][j];
614 let a = augmented[i][j];
615 augmented[k][j] -= factor * a;
616 }
617 }
618 }
619
620 for i in (0..N).rev()
621 {
622 for k in 0..i
623 {
624 let factor = self[k][i];
625 for j in 0..N
626 {
627 let a = self[i][j];
628 self[k][j] -= factor * a;
629 let a = augmented[i][j];
630 augmented[k][j] -= factor * a;
631 }
632 }
633 }
634
635 Some(augmented)
636 }
637}
638
639
640impl<T> SquareMatrix<T, 0> where T: Numeric + One,
646{
647 pub fn det(&self) -> T
648 {
649 T::ONE
650 }
651}
652
653impl<T> SquareMatrix<T, 1> where T: Numeric + One,
654{
655 pub fn det(&self) -> T
656 {
657 self[0][0]
658 }
659}
660
661impl<T> SquareMatrix<T, 2> where T: Numeric + One,
662{
663 pub fn det(&self) -> T
664 {
665 self[0][0] * self[1][1] - self[0][1] * self[1][0]
666 }
667}
668
669impl<T> SquareMatrix<T, 3> where T: Numeric + One,
670{
671 pub fn det(&self) -> T
672 {
673 self[0][0] * (self[1][1] * self[2][2] - self[1][2] * self[2][1])
674 - self[0][1] * (self[1][0] * self[2][2] - self[1][2] * self[2][0])
675 + self[0][2] * (self[1][0] * self[2][1] - self[1][1] * self[2][0])
676 }
677}
678
679impl<T> SquareMatrix<T, 4> where T: Numeric + One,
680{
681 pub fn det(&self) -> T
682 {
683 let a = self[2][2] * self[3][3] - self[2][3] * self[3][2];
684 let b = self[2][1] * self[3][3] - self[2][3] * self[3][1];
685 let c = self[2][1] * self[3][2] - self[2][2] * self[3][1];
686 let d = self[2][0] * self[3][3] - self[2][3] * self[3][0];
687 let e = self[2][0] * self[3][2] - self[2][2] * self[3][0];
688 let f = self[2][0] * self[3][1] - self[2][1] * self[3][0];
689
690 self[0][0] *
691 (
692 self[1][1] * a
693 - self[1][2] * b
694 + self[1][3] * c
695 )
696
697 - self[0][1] *
698 (
699 self[1][0] * a
700 - self[1][2] * d
701 + self[1][3] * e
702 )
703
704 + self[0][2] *
705 (
706 self[1][0] * b
707 - self[1][1] * d
708 + self[1][3] * f
709 )
710
711 - self[0][3] *
712 (
713 self[1][0] * c
714 - self[1][1] * e
715 + self[1][2] * f
716 )
717 }
718}
719
720
721macro_rules! matrix_have_x {
722 ($dim : expr) =>
723 {
724 impl<T> HaveX<Vector<T,$dim>> for SquareMatrix<T,$dim>
725 {
726 fn iter_x<'a>(&'a self) -> impl Iterator<Item=&'a Vector<T,$dim>> where Vector<T,$dim>: 'a {
727 self.columns.as_array().as_slice()[0..=Self::X_INDEX].iter()
728 }
729
730 fn iter_x_mut<'a>(&'a mut self) -> impl Iterator<Item=&'a mut Vector<T,$dim>> where Vector<T,$dim>: 'a {
731 self.columns.as_array_mut().as_mut_slice()[0..=Self::X_INDEX].iter_mut()
732 }
733 }
734 };
735}
736
737matrix_have_x!(1);
738matrix_have_x!(2);
739matrix_have_x!(3);
740matrix_have_x!(4);
741
742macro_rules! matrix_have_y {
743 ($dim : expr) =>
744 {
745 impl<T> HaveY<Vector<T,$dim>> for SquareMatrix<T,$dim>
746 {
747 fn iter_xy<'a>(&'a self) -> impl Iterator<Item=&'a Vector<T,$dim>> where Vector<T,$dim>: 'a {
748 self.columns.as_array().as_slice()[0..=Self::Y_INDEX].iter()
749 }
750
751 fn iter_xy_mut<'a>(&'a mut self) -> impl Iterator<Item=&'a mut Vector<T,$dim>> where Vector<T,$dim>: 'a {
752 self.columns.as_array_mut().as_mut_slice()[0..=Self::Y_INDEX].iter_mut()
753 }
754 }
755 };
756}
757
758matrix_have_y!(2);
759matrix_have_y!(3);
760matrix_have_y!(4);
761
762macro_rules! matrix_have_z {
763 ($dim : expr) =>
764 {
765 impl<T> HaveZ<Vector<T,$dim>> for SquareMatrix<T,$dim>
766 {
767 fn iter_xyz<'a>(&'a self) -> impl Iterator<Item=&'a Vector<T,$dim>> where Vector<T,$dim>: 'a {
768 self.columns.as_array().as_slice()[0..=Self::Z_INDEX].iter()
769 }
770
771 fn iter_xyz_mut<'a>(&'a mut self) -> impl Iterator<Item=&'a mut Vector<T,$dim>> where Vector<T,$dim>: 'a {
772 self.columns.as_array_mut().as_mut_slice()[0..=Self::Z_INDEX].iter_mut()
773 }
774 }
775 };
776}
777
778matrix_have_z!(3);
779matrix_have_z!(4);
780
781macro_rules! matrix_have_w {
782 ($dim : expr) =>
783 {
784 impl<T> HaveW<Vector<T,$dim>> for SquareMatrix<T,$dim>
785 {
786 fn iter_xyzw<'a>(&'a self) -> impl Iterator<Item=&'a Vector<T,$dim>> where Vector<T,$dim>: 'a {
787 self.columns.as_array().as_slice()[0..=Self::W_INDEX].iter()
788 }
789
790 fn iter_xyzw_mut<'a>(&'a mut self) -> impl Iterator<Item=&'a mut Vector<T,$dim>> where Vector<T,$dim>: 'a {
791 self.columns.as_array_mut().as_mut_slice()[0..=Self::W_INDEX].iter_mut()
792 }
793 }
794 };
795}
796
797matrix_have_w!(4);
798
799impl<T, const N : usize> RotateX<T> for SquareMatrix<T,N>
800 where
801 Self : HaveZ<Vector<T,N>> + Zero + Mul<Self, Output = Self>,
802 T : Float
803{
804 fn rotate_x(&mut self, angle : AngleOf<T>) -> &mut Self
805 {
806 *self = Self::from_rotation_x(angle) * (*self);
807 self
808 }
809}
810
811impl<T, const N : usize> RotateY<T> for SquareMatrix<T,N>
812 where
813 Self : HaveZ<Vector<T,N>> + Zero + Mul<Self, Output = Self>,
814 T : Float
815{
816 fn rotate_y(&mut self, angle : AngleOf<T>) -> &mut Self
817 {
818 *self = Self::from_rotation_y(angle) * (*self);
819 self
820 }
821}
822
823impl<T, const N : usize> RotateZ<T> for SquareMatrix<T,N>
824 where
825 Self : HaveY<Vector<T,N>> + Zero + Mul<Self, Output = Self>,
826 T : Float
827{
828 fn rotate_z(&mut self, angle : AngleOf<T>) -> &mut Self
829 {
830 *self = Self::from_rotation_z(angle) * (*self);
831 self
832 }
833}
834
835impl<T> GetPosition<T,2> for SquareMatrix<T,3> where T: Copy
852{
853 fn pos(&self) -> Vector<T,2> { self.columns[2].into() }
854}
855impl<T> SetPosition<T,2> for SquareMatrix<T,3> where T: Copy
856{
857 fn set_pos(&mut self, pos : Vector<T,2>) -> &mut Self { self.columns[2] = pos.with_z(self[2][2]); self }
858}
859impl<T> GetPosition<T,3> for SquareMatrix<T,4> where T: Copy
860{
861 fn pos(&self) -> Vector<T,3> { self.columns[3].into() }
862}
863impl<T> SetPosition<T,3> for SquareMatrix<T,4> where T: Copy
864{
865 fn set_pos(&mut self, pos : Vector<T,3>) -> &mut Self { self.columns[3] = pos.with_w(self[3][3]); self }
866}
867
868impl<T> GetScale<T,2> for SquareMatrix<T,3> where T: Float
869{
870 fn scale(&self) -> Vector<T,2> { Vector::from_fn(|i| Vector::<T,2>::from(self[i]).length() ) }
871}
872impl<T> SetScale<T,2> for SquareMatrix<T,3> where T: Float
873{
874 fn set_scale(&mut self, scale : Vector<T,2>) -> &mut Self {
875 for i in 0..2
876 {
877 let len = Vector::<T, 2>::from(self[i]).length();
878 if len.is_non_zero()
879 {
880 let factor = scale[i] / len;
881 for j in 0..2
882 {
883 self[i][j] = self[i][j] * factor;
884 }
885 }
886 }
887 self
888 }
889}
890impl<T> GetScale<T,3> for SquareMatrix<T,4> where T: Float
891{
892 fn scale(&self) -> Vector<T,3> { Vector::from_fn(|i| Vector::<T,3>::from(self[i]).length() ) }
893}
894impl<T> SetScale<T,3> for SquareMatrix<T,4> where T: Float
895{
896 fn set_scale(&mut self, scale : Vector<T,3>) -> &mut Self {
897 for i in 0..3
898 {
899 let len = Vector::<T, 3>::from(self[i]).length();
900 if len.is_non_zero()
901 {
902 let factor = scale[i] / len;
903 for j in 0..3
904 {
905 self[i][j] = self[i][j] * factor;
906 }
907 }
908 }
909 self
910 }
911}
912
913impl<T, const N : usize> SquareMatrix<T,N> where Self : HaveZ<Vector<T,N>> + Zero, T : Float
915{
916 pub fn from_rotation_axis(axis: Vector3<T>, angle : AngleOf<T>) -> Self
917 {
918 let (sin, cos) = angle.sin_cos();
919 let axis = axis.normalized();
920 let axis_sin = axis * sin;
921 let axis_sq = axis * axis;
922 let omc = T::ONE - cos;
923
924 let xyomc = axis.x * axis.y * omc;
925 let xzomc = axis.x * axis.z * omc;
926 let yzomc = axis.y * axis.z * omc;
927
928 let mut r = Self::ZERO;
929 r[0][0] = axis_sq.x * omc + cos;
930 r[0][1] = xyomc + axis_sin.z;
931 r[0][2] = xzomc - axis_sin.y;
932
933 r[1][0] = xyomc - axis_sin.z;
934 r[1][1] = axis_sq.y * omc + cos;
935 r[1][2] = yzomc + axis_sin.x;
936
937 r[2][0] = xzomc + axis_sin.y;
938 r[2][1] = yzomc - axis_sin.x;
939 r[2][2] = axis_sq.z * omc + cos;
940
941 r
942 }
943
944 pub fn from_rotation_x(angle : AngleOf<T>) -> Self
945 {
946 let (sina, cosa) = angle.sin_cos();
947 let mut r = Self::IDENTITY;
948
949 r[Self::Y_INDEX][Self::Y_INDEX] = cosa;
950 r[Self::Y_INDEX][Self::Z_INDEX] = sina;
951 r[Self::Z_INDEX][Self::Y_INDEX] = -sina;
952 r[Self::Z_INDEX][Self::Z_INDEX] = cosa;
953 r
954 }
955
956 pub fn from_rotation_y(angle : AngleOf<T>) -> Self
957 {
958 let (sina, cosa) = angle.sin_cos();
959 let mut r = Self::IDENTITY;
960
961 r[Self::X_INDEX][Self::X_INDEX] = cosa;
962 r[Self::X_INDEX][Self::Z_INDEX] = -sina;
963 r[Self::Z_INDEX][Self::X_INDEX] = sina;
964 r[Self::Z_INDEX][Self::Z_INDEX] = cosa;
965 r
966 }
967}
968
969impl<T, const N : usize> SquareMatrix<T,N> where Self : HaveY<Vector<T,N>> + Zero, T : Float
970{
971 pub fn from_rotation_z(angle : AngleOf<T>) -> Self
972 {
973 let (sina, cosa) = angle.sin_cos();
974 let mut r = Self::IDENTITY;
975
976 r[Self::X_INDEX][Self::X_INDEX] = cosa;
977 r[Self::X_INDEX][Self::Y_INDEX] = sina;
978 r[Self::Y_INDEX][Self::X_INDEX] = -sina;
979 r[Self::Y_INDEX][Self::Y_INDEX] = cosa;
980 r
981 }
982}
983
984impl<T, const N : usize> SquareMatrix<T,N> where Self : HaveZ<Vector<T,N>> + One, T : Copy + Zero + One
985{
986 pub fn from_scale(scale : Vector<T,N>) -> Self
988 {
989 let mut r = Self::IDENTITY;
992 for i in 0..N
993 {
994 r[i][i] = scale[i];
995 }
996 r
997 }
998 pub fn from_translation(translation: Vector<T,N>) -> Self where T: Zero + AddAssign<T>
1000 {
1001 let mut r = Self::IDENTITY;
1003 for i in 0..N
1004 {
1005 r[N-1][i] += translation[i];
1006 }
1007 r
1008 }
1009}
1010
1011
1012impl<T> Matrix4<T>
1014{
1015 #[inline]
1019 #[must_use]
1020 pub fn look_at_rh(position: Vector3<T>, center: Vector3<T>, up: Vector3<T>) -> Self where T: Float
1021 {
1022 Self::look_to_rh(position, center - position, up)
1023 }
1024
1025 #[inline]
1029 #[must_use]
1030 pub fn look_to_rh(position: Vector3<T>, dir: Vector3<T>, up: Vector3<T>) -> Self where T: Float
1031 {
1032 let f = dir.normalized();
1033 let s = f.cross(up).normalized();
1034 let u = s.cross(f);
1035
1036 Self::from_col(
1037 vector4
1038 (
1039 vector4(s.x, u.x, -f.x, zero()),
1040 vector4(s.y, u.y, -f.y, zero()),
1041 vector4(s.z, u.z, -f.z, zero()),
1042 vector4(-position.dot(s), position.dot(u), position.dot(f), one())
1043 )
1044 )
1045 }
1046
1047
1048 #[inline]
1052 #[must_use]
1053 pub fn look_at_lh(position: Vector3<T>, center: Vector3<T>, up: Vector3<T>) -> Self where T: Float,
1054 {
1055 Self::look_to_lh(position, center - position, up)
1056 }
1057
1058 #[inline]
1062 #[must_use]
1063 pub fn look_to_lh(position: Vector3<T>, dir: Vector3<T>, up: Vector3<T>) -> Self where T: Float,
1064 {
1065 let f = dir.normalized();
1066 let s = up.cross(f).normalized();
1067 let u = f.cross(s);
1068
1069 Self::from_col(
1070 vector4(
1071 vector4(s.x, u.x, f.x, zero()),
1072 vector4(s.y, u.y, f.y, zero()),
1073 vector4(s.z, u.z, f.z, zero()),
1074 vector4(-position.dot(s), -position.dot(u), -position.dot(f), one()),
1075 )
1076 )
1077 }
1078}
1079
1080
1081#[cfg(test)]
1082mod test_matrix
1083{
1084 use super::*;
1085
1086 #[test]
1087 fn rotation_zero_on_z()
1088 {
1089 let m = Mat2::from_col_array([[1.,2.], [3.,4.]]);
1090 assert_eq!(m.rotated_z(0.degree()), m);
1091 }
1092}