use crate::allocator::Allocator; use crate::geometry::{Rotation, UnitComplex, UnitQuaternion}; use crate::{DefaultAllocator, DimName, Point, Scalar, SimdRealField, Unit, VectorN, U2, U3}; use simba::scalar::ClosedMul; /// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`. pub trait AbstractRotation: PartialEq + ClosedMul + Clone { /// The rotation identity. fn identity() -> Self; /// The rotation inverse. fn inverse(&self) -> Self; /// Change `self` to its inverse. fn inverse_mut(&mut self); /// Apply the rotation to the given vector. fn transform_vector(&self, v: &VectorN) -> VectorN where DefaultAllocator: Allocator; /// Apply the rotation to the given point. fn transform_point(&self, p: &Point) -> Point where DefaultAllocator: Allocator; /// Apply the inverse rotation to the given vector. fn inverse_transform_vector(&self, v: &VectorN) -> VectorN where DefaultAllocator: Allocator; /// Apply the inverse rotation to the given unit vector. fn inverse_transform_unit_vector(&self, v: &Unit>) -> Unit> where DefaultAllocator: Allocator, { Unit::new_unchecked(self.inverse_transform_vector(&**v)) } /// Apply the inverse rotation to the given point. fn inverse_transform_point(&self, p: &Point) -> Point where DefaultAllocator: Allocator; } impl AbstractRotation for Rotation where N::Element: SimdRealField, DefaultAllocator: Allocator, { #[inline] fn identity() -> Self { Self::identity() } #[inline] fn inverse(&self) -> Self { self.inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } #[inline] fn transform_vector(&self, v: &VectorN) -> VectorN where DefaultAllocator: Allocator, { self * v } #[inline] fn transform_point(&self, p: &Point) -> Point where DefaultAllocator: Allocator, { self * p } #[inline] fn inverse_transform_vector(&self, v: &VectorN) -> VectorN where DefaultAllocator: Allocator, { self.inverse_transform_vector(v) } #[inline] fn inverse_transform_unit_vector(&self, v: &Unit>) -> Unit> where DefaultAllocator: Allocator, { self.inverse_transform_unit_vector(v) } #[inline] fn inverse_transform_point(&self, p: &Point) -> Point where DefaultAllocator: Allocator, { self.inverse_transform_point(p) } } impl AbstractRotation for UnitQuaternion where N::Element: SimdRealField, { #[inline] fn identity() -> Self { Self::identity() } #[inline] fn inverse(&self) -> Self { self.inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } #[inline] fn transform_vector(&self, v: &VectorN) -> VectorN { self * v } #[inline] fn transform_point(&self, p: &Point) -> Point { self * p } #[inline] fn inverse_transform_vector(&self, v: &VectorN) -> VectorN { self.inverse_transform_vector(v) } #[inline] fn inverse_transform_point(&self, p: &Point) -> Point { self.inverse_transform_point(p) } } impl AbstractRotation for UnitComplex where N::Element: SimdRealField, { #[inline] fn identity() -> Self { Self::identity() } #[inline] fn inverse(&self) -> Self { self.inverse() } #[inline] fn inverse_mut(&mut self) { self.inverse_mut() } #[inline] fn transform_vector(&self, v: &VectorN) -> VectorN { self * v } #[inline] fn transform_point(&self, p: &Point) -> Point { self * p } #[inline] fn inverse_transform_vector(&self, v: &VectorN) -> VectorN { self.inverse_transform_vector(v) } #[inline] fn inverse_transform_point(&self, p: &Point) -> Point { self.inverse_transform_point(p) } }