rgeometry/
transformation.rs

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// Sigh, can't use nalgebra::Transform because it requires RealField + Copy.
17// ndarray also requires Copy.
18// Use const generics once const_generics and const_evaluatable_checked are stable.
19#[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
97// &t * &v = v
98impl<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
115// &t * v = v
116impl<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}