1#[allow(unused_imports)]
2use array_init::array_init;
3use num_traits::identities::One;
4use num_traits::identities::Zero;
5use std::ops::Div;
6use std::ops::Mul;
7
8use crate::data::Point;
9use crate::data::Polygon;
10use crate::data::Vector;
11use crate::matrix::{Matrix, MatrixMul};
12
13pub trait TransformScalar: One + Zero + Div<Output = Self> + MatrixMul {}
14impl<T> TransformScalar for T where T: One + Zero + Div<Output = Self> + MatrixMul {}
15
16#[derive(Clone, Debug)]
20pub struct Transform<T, const N: usize>(Matrix<T>);
21
22impl<T, const N: usize> Transform<T, N>
23where
24 T: TransformScalar,
25{
26 fn new(m: Matrix<T>) -> Transform<T, N> {
27 assert_eq!(m.ncols(), N + 1);
28 assert_eq!(m.nrows(), N + 1);
29 Transform(m)
30 }
31 pub fn translate(vec: Vector<T, N>) -> Transform<T, N> {
32 let mut m = Matrix::new(N + 1, N + 1);
33 for i in 0..N {
34 m[(i, i)] = T::one();
35 m[(i, N)] = vec[i].clone();
36 }
37 m[(N, N)] = T::one();
38 Transform::new(m)
39 }
40
41 pub fn scale(vec: Vector<T, N>) -> Transform<T, N>
42 where
43 T: One + Zero,
44 {
45 let mut m = Matrix::new(N + 1, N + 1);
46 for i in 0..N {
47 m[(i, i)] = vec[i].clone();
48 }
49 m[(N, N)] = T::one();
50 Transform::new(m)
51 }
52
53 pub fn uniform_scale(v: T) -> Transform<T, N>
54 where
55 T: One + Zero,
56 {
57 let mut m = Matrix::new(N + 1, N + 1);
58 for i in 0..N {
59 m[(i, i)] = v.clone();
60 }
61 m[(N, N)] = T::one();
62 Transform::new(m)
63 }
64}
65
66impl<T, const N: usize> Mul for Transform<T, N>
67where
68 T: TransformScalar,
69{
70 type Output = Transform<T, N>;
71 fn mul(self, other: Transform<T, N>) -> Transform<T, N> {
72 Transform::new(self.0 * other.0)
73 }
74}
75
76impl<T, const N: usize> Mul<&Transform<T, N>> for &Transform<T, N>
77where
78 T: TransformScalar,
79{
80 type Output = Transform<T, N>;
81 fn mul(self, other: &Transform<T, N>) -> Transform<T, N> {
82 Transform::new(&self.0 * &other.0)
83 }
84}
85
86impl<T, const N: usize> Mul<&Point<T, N>> for &Transform<T, N>
87where
88 T: TransformScalar,
89{
90 type Output = Point<T, N>;
91 fn mul(self, other: &Point<T, N>) -> Point<T, N> {
92 let v: Vector<T, N> = self * Vector::from(other.clone());
93 v.into()
94 }
95}
96
97impl<T, const N: usize> Mul<&Vector<T, N>> for &Transform<T, N>
99where
100 T: TransformScalar,
101{
102 type Output = Vector<T, N>;
103 fn mul(self, other: &Vector<T, N>) -> Vector<T, N> {
104 let mut v = Matrix::new(N + 1, 1);
105 for i in 0..N {
106 v[(i, 0)] = other.0[i].clone()
107 }
108 v[(N, 0)] = T::one();
109 let ret = &self.0 * v;
110 let normalizer = ret[(N, 0)].clone();
111 Vector(array_init(|i| ret[(i, 0)].clone() / normalizer.clone()))
112 }
113}
114
115impl<T, const N: usize> Mul<Vector<T, N>> for &Transform<T, N>
117where
118 T: TransformScalar,
119{
120 type Output = Vector<T, N>;
121 fn mul(self, other: Vector<T, N>) -> Vector<T, N> {
122 self.mul(&other)
123 }
124}
125
126impl<T, const N: usize> Mul<&Vector<T, N>> for Transform<T, N>
127where
128 T: TransformScalar,
129{
130 type Output = Vector<T, N>;
131 fn mul(self, other: &Vector<T, N>) -> Vector<T, N> {
132 (&self).mul(other)
133 }
134}
135
136impl<T, const N: usize> Mul<Point<T, N>> for Transform<T, N>
137where
138 T: TransformScalar,
139{
140 type Output = Point<T, N>;
141 fn mul(self, other: Point<T, N>) -> Point<T, N> {
142 &self * &other
143 }
144}
145
146impl<T, const N: usize> Mul<Point<T, N>> for &Transform<T, N>
147where
148 T: TransformScalar,
149{
150 type Output = Point<T, N>;
151 fn mul(self, other: Point<T, N>) -> Point<T, N> {
152 self * &other
153 }
154}
155
156impl<T> Mul<&Polygon<T>> for &Transform<T, 2>
157where
158 T: TransformScalar,
159{
160 type Output = Polygon<T>;
161 fn mul(self, other: &Polygon<T>) -> Polygon<T> {
162 other.clone().map_points(|p| self * p)
163 }
164}
165
166impl<T> Mul<Polygon<T>> for &Transform<T, 2>
167where
168 T: TransformScalar,
169{
170 type Output = Polygon<T>;
171 fn mul(self, mut other: Polygon<T>) -> Polygon<T> {
172 for pt in other.iter_mut() {
173 *pt = self * pt.clone();
174 }
175 other
176 }
177}
178
179impl<T> Mul<Polygon<T>> for Transform<T, 2>
180where
181 T: TransformScalar,
182{
183 type Output = Polygon<T>;
184 fn mul(self, other: Polygon<T>) -> Polygon<T> {
185 (&self).mul(other)
186 }
187}
188
189impl<T> Mul<&Polygon<T>> for Transform<T, 2>
190where
191 T: TransformScalar,
192{
193 type Output = Polygon<T>;
194 fn mul(self, other: &Polygon<T>) -> Polygon<T> {
195 (&self).mul(other)
196 }
197}