1use std::fmt;
17use std::iter;
18use std::ops::*;
19
20use structure::*;
21
22use angle::Rad;
23use approx;
24use euler::Euler;
25use matrix::{Matrix2, Matrix3};
26use num::BaseFloat;
27use point::{Point2, Point3};
28use quaternion::Quaternion;
29use vector::{Vector2, Vector3};
30
31pub trait Rotation: Sized + Copy + One
34where
35 Self: approx::AbsDiffEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
37 Self: approx::RelativeEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
38 Self: approx::UlpsEq<Epsilon = <<Self as Rotation>::Space as EuclideanSpace>::Scalar>,
39 <Self::Space as EuclideanSpace>::Scalar: BaseFloat,
40 Self: iter::Product<Self>,
41{
42 type Space: EuclideanSpace;
43
44 fn look_at(
46 dir: <Self::Space as EuclideanSpace>::Diff,
47 up: <Self::Space as EuclideanSpace>::Diff,
48 ) -> Self;
49
50 fn between_vectors(
53 a: <Self::Space as EuclideanSpace>::Diff,
54 b: <Self::Space as EuclideanSpace>::Diff,
55 ) -> Self;
56
57 fn rotate_vector(
59 &self,
60 vec: <Self::Space as EuclideanSpace>::Diff,
61 ) -> <Self::Space as EuclideanSpace>::Diff;
62
63 #[inline]
66 fn rotate_point(&self, point: Self::Space) -> Self::Space {
67 Self::Space::from_vec(self.rotate_vector(point.to_vec()))
68 }
69
70 fn invert(&self) -> Self;
73}
74
75pub trait Rotation2:
77 Rotation<Space = Point2<<Self as Rotation2>::Scalar>>
78 + Into<Matrix2<<Self as Rotation2>::Scalar>>
79 + Into<Basis2<<Self as Rotation2>::Scalar>>
80{
81 type Scalar: BaseFloat;
82
83 fn from_angle<A: Into<Rad<Self::Scalar>>>(theta: A) -> Self;
86}
87
88pub trait Rotation3:
90 Rotation<Space = Point3<<Self as Rotation3>::Scalar>>
91 + Into<Matrix3<<Self as Rotation3>::Scalar>>
92 + Into<Basis3<<Self as Rotation3>::Scalar>>
93 + Into<Quaternion<<Self as Rotation3>::Scalar>>
94 + From<Euler<Rad<<Self as Rotation3>::Scalar>>>
95{
96 type Scalar: BaseFloat;
97
98 fn from_axis_angle<A: Into<Rad<Self::Scalar>>>(axis: Vector3<Self::Scalar>, angle: A) -> Self;
102
103 #[inline]
105 fn from_angle_x<A: Into<Rad<Self::Scalar>>>(theta: A) -> Self {
106 Rotation3::from_axis_angle(Vector3::unit_x(), theta)
107 }
108
109 #[inline]
111 fn from_angle_y<A: Into<Rad<Self::Scalar>>>(theta: A) -> Self {
112 Rotation3::from_axis_angle(Vector3::unit_y(), theta)
113 }
114
115 #[inline]
117 fn from_angle_z<A: Into<Rad<Self::Scalar>>>(theta: A) -> Self {
118 Rotation3::from_axis_angle(Vector3::unit_z(), theta)
119 }
120}
121
122#[derive(PartialEq, Copy, Clone)]
166#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
167pub struct Basis2<S> {
168 mat: Matrix2<S>,
169}
170
171impl<S: BaseFloat> Basis2<S> {
172 pub fn look_at_stable(dir: Vector2<S>, flip: bool) -> Basis2<S> {
173 Basis2 {
174 mat: Matrix2::look_at_stable(dir, flip),
175 }
176 }
177}
178
179impl<S: BaseFloat> AsRef<Matrix2<S>> for Basis2<S> {
180 #[inline]
181 fn as_ref(&self) -> &Matrix2<S> {
182 &self.mat
183 }
184}
185
186impl<S: BaseFloat> From<Basis2<S>> for Matrix2<S> {
187 #[inline]
188 fn from(b: Basis2<S>) -> Matrix2<S> {
189 b.mat
190 }
191}
192
193impl<S: BaseFloat> iter::Product<Basis2<S>> for Basis2<S> {
194 #[inline]
195 fn product<I: Iterator<Item = Basis2<S>>>(iter: I) -> Basis2<S> {
196 iter.fold(Basis2::one(), Mul::mul)
197 }
198}
199
200impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis2<S>> for Basis2<S> {
201 #[inline]
202 fn product<I: Iterator<Item = &'a Basis2<S>>>(iter: I) -> Basis2<S> {
203 iter.fold(Basis2::one(), Mul::mul)
204 }
205}
206
207impl<S: BaseFloat> Rotation for Basis2<S> {
208 type Space = Point2<S>;
209
210 #[inline]
211 fn look_at(dir: Vector2<S>, up: Vector2<S>) -> Basis2<S> {
212 Basis2 {
213 mat: Matrix2::look_at(dir, up),
214 }
215 }
216
217 #[inline]
218 fn between_vectors(a: Vector2<S>, b: Vector2<S>) -> Basis2<S> {
219 Rotation2::from_angle(Rad::acos(a.dot(b)))
220 }
221
222 #[inline]
223 fn rotate_vector(&self, vec: Vector2<S>) -> Vector2<S> {
224 self.mat * vec
225 }
226
227 #[inline]
230 fn invert(&self) -> Basis2<S> {
231 Basis2 {
232 mat: self.mat.invert().unwrap(),
233 }
234 }
235}
236
237impl<S: BaseFloat> One for Basis2<S> {
238 #[inline]
239 fn one() -> Basis2<S> {
240 Basis2 {
241 mat: Matrix2::one(),
242 }
243 }
244}
245
246impl_operator!(<S: BaseFloat> Mul<Basis2<S> > for Basis2<S> {
247 fn mul(lhs, rhs) -> Basis2<S> { Basis2 { mat: lhs.mat * rhs.mat } }
248});
249
250impl<S: BaseFloat> approx::AbsDiffEq for Basis2<S> {
251 type Epsilon = S::Epsilon;
252
253 #[inline]
254 fn default_epsilon() -> S::Epsilon {
255 S::default_epsilon()
256 }
257
258 #[inline]
259 fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon) -> bool {
260 Matrix2::abs_diff_eq(&self.mat, &other.mat, epsilon)
261 }
262}
263
264impl<S: BaseFloat> approx::RelativeEq for Basis2<S> {
265 #[inline]
266 fn default_max_relative() -> S::Epsilon {
267 S::default_max_relative()
268 }
269
270 #[inline]
271 fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
272 Matrix2::relative_eq(&self.mat, &other.mat, epsilon, max_relative)
273 }
274}
275
276impl<S: BaseFloat> approx::UlpsEq for Basis2<S> {
277 #[inline]
278 fn default_max_ulps() -> u32 {
279 S::default_max_ulps()
280 }
281
282 #[inline]
283 fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
284 Matrix2::ulps_eq(&self.mat, &other.mat, epsilon, max_ulps)
285 }
286}
287
288impl<S: BaseFloat> Rotation2 for Basis2<S> {
289 type Scalar = S;
290
291 fn from_angle<A: Into<Rad<S>>>(theta: A) -> Basis2<S> {
292 Basis2 {
293 mat: Matrix2::from_angle(theta),
294 }
295 }
296}
297
298impl<S: fmt::Debug> fmt::Debug for Basis2<S> {
299 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
300 write!(f, "Basis2 ")?;
301 <[[S; 2]; 2] as fmt::Debug>::fmt(self.mat.as_ref(), f)
302 }
303}
304
305#[derive(PartialEq, Copy, Clone)]
312#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
313pub struct Basis3<S> {
314 mat: Matrix3<S>,
315}
316
317impl<S: BaseFloat> Basis3<S> {
318 #[inline]
320 pub fn from_quaternion(quaternion: &Quaternion<S>) -> Basis3<S> {
321 Basis3 {
322 mat: quaternion.clone().into(),
323 }
324 }
325}
326
327impl<S> AsRef<Matrix3<S>> for Basis3<S> {
328 #[inline]
329 fn as_ref(&self) -> &Matrix3<S> {
330 &self.mat
331 }
332}
333
334impl<S: BaseFloat> From<Basis3<S>> for Matrix3<S> {
335 #[inline]
336 fn from(b: Basis3<S>) -> Matrix3<S> {
337 b.mat
338 }
339}
340
341impl<S: BaseFloat> From<Basis3<S>> for Quaternion<S> {
342 #[inline]
343 fn from(b: Basis3<S>) -> Quaternion<S> {
344 b.mat.into()
345 }
346}
347
348impl<S: BaseFloat> iter::Product<Basis3<S>> for Basis3<S> {
349 #[inline]
350 fn product<I: Iterator<Item = Basis3<S>>>(iter: I) -> Basis3<S> {
351 iter.fold(Basis3::one(), Mul::mul)
352 }
353}
354
355impl<'a, S: 'a + BaseFloat> iter::Product<&'a Basis3<S>> for Basis3<S> {
356 #[inline]
357 fn product<I: Iterator<Item = &'a Basis3<S>>>(iter: I) -> Basis3<S> {
358 iter.fold(Basis3::one(), Mul::mul)
359 }
360}
361
362impl<S: BaseFloat> Rotation for Basis3<S> {
363 type Space = Point3<S>;
364
365 #[inline]
366 fn look_at(dir: Vector3<S>, up: Vector3<S>) -> Basis3<S> {
367 Basis3 {
368 mat: Matrix3::look_to_lh(dir, up),
369 }
370 }
371
372 #[inline]
373 fn between_vectors(a: Vector3<S>, b: Vector3<S>) -> Basis3<S> {
374 let q: Quaternion<S> = Rotation::between_vectors(a, b);
375 q.into()
376 }
377
378 #[inline]
379 fn rotate_vector(&self, vec: Vector3<S>) -> Vector3<S> {
380 self.mat * vec
381 }
382
383 #[inline]
386 fn invert(&self) -> Basis3<S> {
387 Basis3 {
388 mat: self.mat.invert().unwrap(),
389 }
390 }
391}
392
393impl<S: BaseFloat> One for Basis3<S> {
394 #[inline]
395 fn one() -> Basis3<S> {
396 Basis3 {
397 mat: Matrix3::one(),
398 }
399 }
400}
401
402impl_operator!(<S: BaseFloat> Mul<Basis3<S> > for Basis3<S> {
403 fn mul(lhs, rhs) -> Basis3<S> { Basis3 { mat: lhs.mat * rhs.mat } }
404});
405
406impl<S: BaseFloat> approx::AbsDiffEq for Basis3<S> {
407 type Epsilon = S::Epsilon;
408
409 #[inline]
410 fn default_epsilon() -> S::Epsilon {
411 S::default_epsilon()
412 }
413
414 #[inline]
415 fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon) -> bool {
416 Matrix3::abs_diff_eq(&self.mat, &other.mat, epsilon)
417 }
418}
419
420impl<S: BaseFloat> approx::RelativeEq for Basis3<S> {
421 #[inline]
422 fn default_max_relative() -> S::Epsilon {
423 S::default_max_relative()
424 }
425
426 #[inline]
427 fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
428 Matrix3::relative_eq(&self.mat, &other.mat, epsilon, max_relative)
429 }
430}
431
432impl<S: BaseFloat> approx::UlpsEq for Basis3<S> {
433 #[inline]
434 fn default_max_ulps() -> u32 {
435 S::default_max_ulps()
436 }
437
438 #[inline]
439 fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
440 Matrix3::ulps_eq(&self.mat, &other.mat, epsilon, max_ulps)
441 }
442}
443
444impl<S: BaseFloat> Rotation3 for Basis3<S> {
445 type Scalar = S;
446
447 fn from_axis_angle<A: Into<Rad<S>>>(axis: Vector3<S>, angle: A) -> Basis3<S> {
448 Basis3 {
449 mat: Matrix3::from_axis_angle(axis, angle),
450 }
451 }
452
453 fn from_angle_x<A: Into<Rad<S>>>(theta: A) -> Basis3<S> {
454 Basis3 {
455 mat: Matrix3::from_angle_x(theta),
456 }
457 }
458
459 fn from_angle_y<A: Into<Rad<S>>>(theta: A) -> Basis3<S> {
460 Basis3 {
461 mat: Matrix3::from_angle_y(theta),
462 }
463 }
464
465 fn from_angle_z<A: Into<Rad<S>>>(theta: A) -> Basis3<S> {
466 Basis3 {
467 mat: Matrix3::from_angle_z(theta),
468 }
469 }
470}
471
472impl<A: Angle> From<Euler<A>> for Basis3<A::Unitless>
473where
474 A: Into<Rad<<A as Angle>::Unitless>>,
475{
476 fn from(src: Euler<A>) -> Basis3<A::Unitless> {
478 Basis3 {
479 mat: Matrix3::from(src),
480 }
481 }
482}
483
484impl<S: fmt::Debug> fmt::Debug for Basis3<S> {
485 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
486 write!(f, "Basis3 ")?;
487 <[[S; 3]; 3] as fmt::Debug>::fmt(self.mat.as_ref(), f)
488 }
489}