1use crate::ops::Skew;
7use math::{Matrix3, RealField, Vector3};
8use num_traits::Zero;
9
10pub trait Scale<T: Clone> {
11 fn scale(&mut self, s: [T; 3]);
14 fn uniform_scale(&mut self, s: T) {
16 self.scale([s.clone(), s.clone(), s]);
17 }
18}
19
20pub trait Rotate<T: RealField> {
23 fn rotate_by_matrix(&mut self, mtx: [[T; 3]; 3]);
25
26 fn rotate(&mut self, axis: [T; 3], theta: T) {
31 let u = Vector3::from(axis.clone());
32 let [x, y, z] = axis;
33 let id = Matrix3::identity();
34 let u_skew = u.skew();
35 let cos_theta = theta.clone().cos();
36
37 let u_v_t = {
41 let [a, b, c]: [T; 3] = (u * (T::one() - cos_theta.clone())).into();
42 Matrix3::from([
43 [x.clone() * a.clone(), x.clone() * b.clone(), x * c.clone()],
44 [y.clone() * a.clone(), y.clone() * b.clone(), y * c.clone()],
45 [z.clone() * a, z.clone() * b, z * c],
46 ])
47 };
48 let mtx = id * cos_theta + u_skew * theta.sin() + u_v_t;
49 self.rotate_by_matrix(mtx.into());
50 }
51
52 fn rotate_by_vector(&mut self, e: [T; 3])
55 where
56 T: Zero,
57 {
58 let e = Vector3::from(e);
59 let theta = e.norm();
60 if theta == T::zero() {
61 return;
62 }
63
64 let u = e / theta.clone();
65 self.rotate(u.into(), theta);
66 }
67}
68
69pub trait Translate<T> {
70 fn translate(&mut self, t: [T; 3]);
72}
73
74pub trait Scaled<T>
79where
80 Self: Sized,
81{
82 fn scaled(self, s: [T; 3]) -> Self;
84 fn uniformly_scaled(self, s: T) -> Self;
86}
87
88pub trait Rotated<T>
89where
90 Self: Sized,
91{
92 fn rotated(self, u: [T; 3], theta: T) -> Self;
98 fn rotated_by_matrix(self, mtx: [[T; 3]; 3]) -> Self;
100 fn rotated_by_vector(self, e: [T; 3]) -> Self;
102}
103
104pub trait Translated<T>
105where
106 Self: Sized,
107{
108 fn translated(self, t: [T; 3]) -> Self;
110}
111
112impl<S, T: Copy> Scaled<T> for S
113where
114 S: Scale<T> + Sized,
115{
116 fn scaled(mut self, s: [T; 3]) -> Self {
117 self.scale(s);
118 self
119 }
120 fn uniformly_scaled(mut self, s: T) -> Self {
121 self.uniform_scale(s);
122 self
123 }
124}
125
126impl<S, T: RealField> Rotated<T> for S
127where
128 S: Rotate<T> + Sized,
129{
130 fn rotated(mut self, u: [T; 3], theta: T) -> Self {
131 self.rotate(u, theta);
132 self
133 }
134 fn rotated_by_matrix(mut self, mtx: [[T; 3]; 3]) -> Self {
135 self.rotate_by_matrix(mtx);
136 self
137 }
138 fn rotated_by_vector(mut self, e: [T; 3]) -> Self {
139 self.rotate_by_vector(e);
140 self
141 }
142}
143
144impl<S, T> Translated<T> for S
145where
146 S: Translate<T> + Sized,
147{
148 fn translated(mut self, t: [T; 3]) -> Self {
149 self.translate(t);
150 self
151 }
152}