1#[allow(unused_imports)]
2use std::ops::Div;
3#[allow(unused_imports)]
4use std::ops::Index;
5#[allow(unused_imports)]
6use std::ops::IndexMut;
7
8use crate::matrix::*;
10use crate::scalar::Scalar;
11
12use std::ops::{Add, Mul, Sub};
13
14use num_traits::{real::Real, NumAssign};
15
16#[derive(Clone, Debug)]
17pub struct Quat<T: Real + NumAssign + Default + Clone>(pub Matrix<T, 1, 4>);
18
19macro_rules! impl_quat_partialeq_float {
20 ($type:ty) => {
21 impl PartialEq<Quat<$type>> for Quat<$type> {
22 fn eq(&self, other: &Self) -> bool {
23 (&self.0).eq(&other.0)
24 }
25 }
26 };
27}
28
29impl_quat_partialeq_float!(f32);
30impl_quat_partialeq_float!(f64);
31
32impl<T: Real + NumAssign + Default> Default for Quat<T> {
33 fn default() -> Quat<T> {
34 Quat(Matrix::from([[T::zero(), T::zero(), T::zero(), T::one()]]))
35 }
36}
37
38impl<T: Real + Default + NumAssign> Quat<T> {
39 pub fn x(&self) -> T {
40 self.0[[0, 0]]
41 }
42 pub fn y(&self) -> T {
43 self.0[[0, 1]]
44 }
45 pub fn z(&self) -> T {
46 self.0[[0, 2]]
47 }
48 pub fn w(&self) -> T {
49 self.0[[0, 3]]
50 }
51 pub fn x_mut(&mut self) -> &mut T {
52 &mut self.0[[0, 0]]
53 }
54 pub fn y_mut(&mut self) -> &mut T {
55 &mut self.0[[0, 1]]
56 }
57 pub fn z_mut(&mut self) -> &mut T {
58 &mut self.0[[0, 2]]
59 }
60 pub fn w_mut(&mut self) -> &mut T {
61 &mut self.0[[0, 3]]
62 }
63 pub fn init(x: T, y: T, z: T, w: T) -> Self {
64 Quat(Matrix::from([[x, y, z, w]]))
65 }
66 pub fn add(&self, other: &Self) -> Self {
92 Quat::init(
93 self.x() + other.x(),
94 self.y() + other.y(),
95 self.z() + other.z(),
96 self.w() + other.w(),
97 )
98 }
99 pub fn minus(&self, other: &Self) -> Self {
100 Quat::init(
101 self.x() - other.x(),
102 self.y() - other.y(),
103 self.z() - other.z(),
104 self.w() - other.w(),
105 )
106 }
107 pub fn mul(&self, other: &Self) -> Self {
108 Quat::init(
109 self.w() * other.x() + self.x() * other.w() + self.y() * other.z()
110 - self.z() * other.y(),
111 self.w() * other.y() - self.x() * other.z()
112 + self.y() * other.w()
113 + self.z() * other.x(),
114 self.w() * other.z() + self.x() * other.y() - self.y() * other.x()
115 + self.z() * other.w(),
116 self.w() * other.w()
117 - self.x() * other.x()
118 - self.y() * other.y()
119 - self.z() * other.z(),
120 )
121 }
122 pub fn norm_squared(&self) -> T {
123 self.x() * self.x() + self.y() * self.y() + self.z() * self.z() + self.w() * self.w()
124 }
125 pub fn norm(&self) -> T {
126 self.norm_squared().sqrt()
127 }
128 pub fn normalize(&self) -> Self {
129 let l = self.norm();
130 if l > T::zero() || l < T::zero() {
131 Quat::init(self.x() / l, self.y() / l, self.z() / l, self.w() / l)
132 } else {
133 panic!("quat normalization unsuccessful.");
134 }
135 }
136 pub fn normalized(&mut self) {
137 let l = self.norm();
138 if l > T::zero() || l < T::zero() {
139 *self.x_mut() = self.x() / l;
140 *self.y_mut() = self.y() / l;
141 *self.z_mut() = self.z() / l;
142 *self.w_mut() = self.w() / l;
143 } else {
144 panic!("quat normalization unsuccessful.");
145 }
146 }
147 pub fn ln(&self) -> Self {
148 let l = self.norm();
149 let w_ln = self.w().ln();
150 let vec_length = (self.x() * self.x() + self.y() * self.y() + self.z() * self.z()).sqrt();
152 assert!(vec_length != T::zero());
153 let vec_x = self.x() / vec_length;
154 let vec_y = self.y() / vec_length;
155 let vec_z = self.z() / vec_length;
156 let s = (w_ln / l).acos();
158 Quat::init(vec_x * s, vec_y * s, vec_z * s, w_ln)
159 }
160 pub fn pow(&self, t: T) -> Self {
161 let vec_length = (self.x() * self.x() + self.y() * self.y() + self.z() * self.z()).sqrt();
162 assert!(vec_length != T::zero());
163 let vec_x = self.x() / vec_length;
164 let vec_y = self.y() / vec_length;
165 let vec_z = self.z() / vec_length;
166 let l = self.norm();
167 let alpha = (self.w() / l).acos();
169 let beta = t * alpha;
171 let coeff = l.powf(t);
172 Quat::init(
173 coeff * vec_x * beta.sin(),
174 coeff * vec_y * beta.sin(),
175 coeff * vec_z * beta.sin(),
176 coeff * beta.cos(),
177 )
178 }
179 pub fn negate(&self) -> Self {
180 Quat::init(-self.x(), -self.y(), -self.z(), -self.w())
181 }
182 pub fn conjugate(&self) -> Self {
183 Quat::init(-self.x(), -self.y(), -self.z(), self.w())
184 }
185 pub fn scale(&self, s: T) -> Self {
186 Quat::init(self.x() * s, self.y() * s, self.z() * s, self.w() * s)
187 }
188 pub fn scaled(&mut self, s: T) {
189 *self.x_mut() = self.x() * s;
190 *self.y_mut() = self.y() * s;
191 *self.z_mut() = self.z() * s;
192 *self.w_mut() = self.w() * s;
193 }
194 pub fn inverse(&self) -> Self {
195 let conj = self.conjugate();
196 let norm = conj.norm_squared();
197 assert!(norm != T::zero());
198 &conj * (T::one() / norm)
199 }
200 pub fn dot(&self, other: &Self) -> T {
201 self.x() * other.x() + self.y() * other.y() + self.z() * other.z() + self.w() * other.w()
202 }
203 pub fn lerp(start: Quat<T>, end: Quat<T>, t: T) -> Self {
204 let clamp_upper = if t > T::one() { T::one() } else { t };
205 let clamp = if clamp_upper < T::zero() {
206 T::zero()
207 } else {
208 clamp_upper
209 };
210 Quat::init(
211 start.x() * (T::one() - clamp) + end.x() * clamp,
212 start.y() * (T::one() - clamp) + end.y() * clamp,
213 start.z() * (T::one() - clamp) + end.z() * clamp,
214 start.w() * (T::one() - clamp) + end.w() * clamp,
215 )
216 }
217 pub fn slerp(start: Quat<T>, end: Quat<T>, t: T) -> Self {
218 let t_clamp_upper = if t > T::one() { T::one() } else { t };
219 let t_clamp = if t_clamp_upper < T::zero() {
220 T::zero()
221 } else {
222 t_clamp_upper
223 };
224
225 let cos_omega =
226 start.w() * end.w() + start.x() * end.x() + start.y() * end.y() + start.z() * end.z();
227 let cos_omega_adjust = if cos_omega < T::zero() {
228 -cos_omega
229 } else {
230 cos_omega
231 };
232
233 let end_adjust = if cos_omega < T::zero() {
234 Quat::init(-end.x(), -end.y(), -end.z(), -end.w())
236 } else {
237 Quat::init(end.x(), end.y(), end.z(), end.w())
238 };
239
240 let (k0, k1) = if cos_omega_adjust > T::one() - T::epsilon() {
241 (T::one() - t_clamp, t_clamp)
242 } else {
243 let sin_omega = (T::one() - cos_omega * cos_omega).sqrt();
244 let omega = sin_omega.atan2(cos_omega);
245 let inv_sin_omega = T::one() / sin_omega;
246 (
247 ((T::one() - t_clamp) * omega).sin() * inv_sin_omega,
248 (t_clamp * omega).sin() * inv_sin_omega,
249 )
250 };
251 Quat::init(
252 start.x() * k0 + end_adjust.x() * k1,
253 start.y() * k0 + end_adjust.y() * k1,
254 start.z() * k0 + end_adjust.z() * k1,
255 start.w() * k0 + end_adjust.w() * k1,
256 )
257 }
258}
259
260impl<T: Real + Default + NumAssign> Add for &Quat<T> {
261 type Output = Quat<T>;
262 fn add(self, rhs: Self) -> Self::Output {
263 self.add(rhs)
264 }
265}
266
267impl<T: Real + Default + NumAssign> Add for Quat<T> {
268 type Output = Quat<T>;
269 fn add(self, rhs: Self) -> Self::Output {
270 (&self).add(&rhs)
271 }
272}
273
274impl<'a, T: Real + Default + NumAssign> Mul<&'a Quat<T>> for &'a Quat<T> {
275 type Output = Quat<T>;
276 fn mul(self, rhs: Self) -> Self::Output {
277 self.mul(rhs)
278 }
279}
280
281impl<T: Real + Default + NumAssign> Mul<Quat<T>> for Quat<T> {
282 type Output = Quat<T>;
283 fn mul(self, rhs: Self) -> Self::Output {
284 (&self).mul(&rhs)
285 }
286}
287
288impl<T: Real + Default + NumAssign> Mul<T> for &Quat<T> {
289 type Output = Quat<T>;
290 fn mul(self, rhs: T) -> Self::Output {
291 self.scale(rhs)
292 }
293}
294
295impl<T: Real + Default + NumAssign> Mul<T> for Quat<T> {
296 type Output = Quat<T>;
297 fn mul(self, rhs: T) -> Self::Output {
298 self.scale(rhs)
299 }
300}
301
302impl<T: Real + Default + NumAssign> Mul<Scalar<T>> for Quat<T> {
303 type Output = Quat<T>;
304 fn mul(self, rhs: Scalar<T>) -> Self::Output {
305 self.scale(rhs.0)
306 }
307}
308
309impl<T: Real + Default + NumAssign> Mul<&Scalar<T>> for Quat<T> {
310 type Output = Quat<T>;
311 fn mul(self, rhs: &Scalar<T>) -> Self::Output {
312 self.scale(rhs.0)
313 }
314}
315
316impl<T: Real + Default + NumAssign> Mul<Scalar<T>> for &Quat<T> {
317 type Output = Quat<T>;
318 fn mul(self, rhs: Scalar<T>) -> Self::Output {
319 self.scale(rhs.0)
320 }
321}
322
323impl<T: Real + Default + NumAssign> Mul<&Scalar<T>> for &Quat<T> {
324 type Output = Quat<T>;
325 fn mul(self, rhs: &Scalar<T>) -> Self::Output {
326 self.scale(rhs.0)
327 }
328}
329
330impl<T: Real + NumAssign + Copy + Default> Mul<&Quat<T>> for Scalar<T> {
331 type Output = Quat<T>;
332 fn mul(self, rhs: &Quat<T>) -> Self::Output {
333 rhs * self.0
334 }
335}
336
337impl<T: Real + NumAssign + Copy + Default> Mul<Quat<T>> for Scalar<T> {
338 type Output = Quat<T>;
339 fn mul(self, rhs: Quat<T>) -> Self::Output {
340 rhs * self.0
341 }
342}
343
344impl<T: Real + Default + NumAssign> Sub for &Quat<T> {
345 type Output = Quat<T>;
346 fn sub(self, rhs: Self) -> Self::Output {
347 self.minus(rhs)
348 }
349}
350
351impl<T: Real + Default + NumAssign> Sub for Quat<T> {
352 type Output = Quat<T>;
353 fn sub(self, rhs: Self) -> Self::Output {
354 self.minus(&rhs)
355 }
356}
357
358#[test]
359fn convert_float() {
360 struct Test<T: Real>(std::marker::PhantomData<T>);
361 impl<T: Real> Test<T> {
362 pub fn give_me_a_number(&self) -> T {
363 T::from(0.55).unwrap()
364 }
365 }
366 let t = Test::<f32>(std::marker::PhantomData);
367 let num = t.give_me_a_number();
368 assert_eq!(0.55f32, num);
369
370 let t2 = Test::<f64>(std::marker::PhantomData);
371 let num2 = t2.give_me_a_number();
372 assert_eq!(0.55f64, num2);
373}
374
375#[cfg(test)]
376#[derive(Clone, Debug)]
377struct RandQuat<T: Real + NumAssign + Default>(pub Quat<T>);
378
379#[cfg(test)]
380impl<T: Real + Default + NumAssign + 'static> quickcheck::Arbitrary for RandQuat<T> {
381 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
382 let selection = (-100..100).map(|x| T::from(x).unwrap()).collect::<Vec<_>>();
383
384 let q = Quat::init(
385 g.choose(&selection).unwrap().to_owned(),
386 g.choose(&selection).unwrap().to_owned(),
387 g.choose(&selection).unwrap().to_owned(),
388 g.choose(&selection).unwrap().to_owned(),
389 );
390
391 Self(q)
392 }
393}
394
395#[cfg(test)]
396#[quickcheck]
397fn quat_mul_scalar_by_quat(m: RandQuat<f64>) -> bool {
398 let q = m.0;
399 let q2 = Scalar(5.) * &q;
400 matrix_approx_eq_float(
401 &q2.0,
402 &Matrix::<f64, 1, 4>::from([[
403 5. * q.0[[0, 0]],
404 5. * q.0[[0, 1]],
405 5. * q.0[[0, 2]],
406 5. * q.0[[0, 3]],
407 ]]),
408 1e-5,
409 )
410}
411
412#[cfg(test)]
413#[quickcheck]
414fn quat_mul_quat_by_float(m: RandQuat<f64>) -> bool {
415 let q = m.0;
416 let q2 = &q * 5.;
417 matrix_approx_eq_float(
418 &q2.0,
419 &Matrix::<f64, 1, 4>::from([[
420 5. * q.0[[0, 0]],
421 5. * q.0[[0, 1]],
422 5. * q.0[[0, 2]],
423 5. * q.0[[0, 3]],
424 ]]),
425 1e-5,
426 )
427}
428
429#[cfg(test)]
430#[quickcheck]
431fn quat_mul_quat_by_scalar(m: RandQuat<f64>) -> bool {
432 let q = m.0;
433 let q2 = &q * &Scalar(5f64);
434 matrix_approx_eq_float(
435 &q2.0,
436 &Matrix::<f64, 1, 4>::from([[
437 5. * q.0[[0, 0]],
438 5. * q.0[[0, 1]],
439 5. * q.0[[0, 2]],
440 5. * q.0[[0, 3]],
441 ]]),
442 1e-5,
443 )
444}
445
446#[cfg(test)]
447#[quickcheck]
448fn quat_partial_eq_same(m: RandQuat<f64>) -> bool {
449 m.0.eq(&m.0)
450}
451
452#[cfg(test)]
453#[quickcheck]
454fn quat_partial_eq_different((mut m1, mut m2): (RandQuat<f64>, RandQuat<f64>)) -> bool {
455 m1.0 .0[[0, 0]] = 1.0;
456 m2.0 .0[[0, 0]] = 2.0;
457 !m1.0.eq(&m2.0)
458}