2018-05-19 21:41:58 +08:00
use approx ::{ AbsDiffEq , RelativeEq , UlpsEq } ;
2018-02-02 19:26:35 +08:00
use num ::{ One , Zero } ;
2016-12-05 05:44:42 +08:00
use std ::fmt ;
2018-05-19 21:41:58 +08:00
use std ::hash ;
2018-07-20 21:25:55 +08:00
#[ cfg(feature = " abomonation-serialize " ) ]
use std ::io ::{ Result as IOResult , Write } ;
2016-12-05 05:44:42 +08:00
2017-05-04 10:02:30 +08:00
#[ cfg(feature = " serde-serialize " ) ]
2018-10-22 13:00:10 +08:00
use serde ::{ Deserialize , Deserializer , Serialize , Serializer } ;
2017-08-03 01:37:44 +08:00
#[ cfg(feature = " serde-serialize " ) ]
2019-03-23 21:29:07 +08:00
use crate ::base ::storage ::Owned ;
2017-05-04 10:02:30 +08:00
2017-08-14 18:41:03 +08:00
#[ cfg(feature = " abomonation-serialize " ) ]
use abomonation ::Abomonation ;
2020-03-21 19:16:46 +08:00
use simba ::scalar ::RealField ;
2020-03-22 06:22:55 +08:00
use simba ::simd ::SimdRealField ;
2016-12-05 05:44:42 +08:00
2019-03-23 21:29:07 +08:00
use crate ::base ::allocator ::Allocator ;
use crate ::base ::dimension ::{ DimName , DimNameAdd , DimNameSum , U1 } ;
2020-10-25 18:23:34 +08:00
use crate ::base ::{ DefaultAllocator , MatrixN , Scalar , Unit , VectorN } ;
2019-03-31 16:48:59 +08:00
use crate ::geometry ::Point ;
2016-12-05 05:44:42 +08:00
/// A rotation matrix.
2020-11-21 18:21:47 +08:00
///
/// This is also known as an element of a Special Orthogonal (SO) group.
/// The `Rotation` type can either represent a 2D or 3D rotation, represented as a matrix.
/// For a rotation based on quaternions, see [`UnitQuaternion`](crate::UnitQuaternion) instead.
///
/// Note that instead of using the [`Rotation`](crate::Rotation) type in your code directly, you should use one
/// of its aliases: [`Rotation2`](crate::Rotation2), or [`Rotation3`](crate::Rotation3). Though
/// keep in mind that all the documentation of all the methods of these aliases will also appears on
/// this page.
///
/// # Construction
/// * [Identity <span style="float:right;">`identity`</span>](#identity)
/// * [From a 2D rotation angle <span style="float:right;">`new`…</span>](#construction-from-a-2d-rotation-angle)
/// * [From an existing 2D matrix or rotations <span style="float:right;">`from_matrix`, `rotation_between`, `powf`…</span>](#construction-from-an-existing-2d-matrix-or-rotations)
/// * [From a 3D axis and/or angles <span style="float:right;">`new`, `from_euler_angles`, `from_axis_angle`…</span>](#construction-from-a-3d-axis-andor-angles)
/// * [From a 3D eye position and target point <span style="float:right;">`look_at`, `look_at_lh`, `rotation_between`…</span>](#construction-from-a-3d-eye-position-and-target-point)
/// * [From an existing 3D matrix or rotations <span style="float:right;">`from_matrix`, `rotation_between`, `powf`…</span>](#construction-from-an-existing-3d-matrix-or-rotations)
///
/// # Transformation and composition
/// Note that transforming vectors and points can be done by multiplication, e.g., `rotation * point`.
/// Composing an rotation with another transformation can also be done by multiplication or division.
/// * [3D axis and angle extraction <span style="float:right;">`angle`, `euler_angles`, `scaled_axis`, `angle_to`…</span>](#3d-axis-and-angle-extraction)
/// * [2D angle extraction <span style="float:right;">`angle`, `angle_to`…</span>](#2d-angle-extraction)
/// * [Transformation of a vector or a point <span style="float:right;">`transform_vector`, `inverse_transform_point`…</span>](#transformation-of-a-vector-or-a-point)
/// * [Transposition and inversion <span style="float:right;">`transpose`, `inverse`…</span>](#transposition-and-inversion)
/// * [Interpolation <span style="float:right;">`slerp`…</span>](#interpolation)
///
2020-11-21 18:56:24 +08:00
/// # Conversion
2020-11-21 18:21:47 +08:00
/// * [Conversion to a matrix <span style="float:right;">`matrix`, `to_homogeneous`…</span>](#conversion-to-a-matrix)
///
2016-12-05 05:44:42 +08:00
#[ repr(C) ]
2017-08-03 01:37:44 +08:00
#[ derive(Debug) ]
2019-12-17 07:09:14 +08:00
pub struct Rotation < N : Scalar , D : DimName >
2020-04-06 00:49:48 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
2018-02-02 19:26:35 +08:00
{
matrix : MatrixN < N , D > ,
2016-12-05 05:44:42 +08:00
}
2019-12-17 07:09:14 +08:00
impl < N : Scalar + hash ::Hash , D : DimName + hash ::Hash > hash ::Hash for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
< DefaultAllocator as Allocator < N , D , D > > ::Buffer : hash ::Hash ,
{
2017-08-03 01:37:44 +08:00
fn hash < H : hash ::Hasher > ( & self , state : & mut H ) {
self . matrix . hash ( state )
2017-05-04 10:02:30 +08:00
}
}
2019-11-20 04:57:37 +08:00
impl < N : Scalar + Copy , D : DimName > Copy for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
< DefaultAllocator as Allocator < N , D , D > > ::Buffer : Copy ,
2018-11-03 20:35:56 +08:00
{
}
2017-08-03 01:37:44 +08:00
2019-12-17 07:09:14 +08:00
impl < N : Scalar , D : DimName > Clone for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
< DefaultAllocator as Allocator < N , D , D > > ::Buffer : Clone ,
{
2017-08-03 01:37:44 +08:00
#[ inline ]
fn clone ( & self ) -> Self {
2019-02-17 05:29:41 +08:00
Self ::from_matrix_unchecked ( self . matrix . clone ( ) )
2017-05-04 10:02:30 +08:00
}
}
2017-08-14 18:41:03 +08:00
#[ cfg(feature = " abomonation-serialize " ) ]
2017-08-16 01:36:38 +08:00
impl < N , D > Abomonation for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
2019-12-17 07:09:14 +08:00
N : Scalar ,
2018-02-02 19:26:35 +08:00
D : DimName ,
MatrixN < N , D > : Abomonation ,
DefaultAllocator : Allocator < N , D , D > ,
2017-08-14 18:41:03 +08:00
{
2018-07-20 21:25:55 +08:00
unsafe fn entomb < W : Write > ( & self , writer : & mut W ) -> IOResult < ( ) > {
2017-08-14 18:41:03 +08:00
self . matrix . entomb ( writer )
}
2018-07-20 21:25:55 +08:00
fn extent ( & self ) -> usize {
self . matrix . extent ( )
2017-08-14 18:41:03 +08:00
}
unsafe fn exhume < ' a , ' b > ( & ' a mut self , bytes : & ' b mut [ u8 ] ) -> Option < & ' b mut [ u8 ] > {
self . matrix . exhume ( bytes )
}
}
2017-08-03 01:37:44 +08:00
#[ cfg(feature = " serde-serialize " ) ]
2019-12-17 07:09:14 +08:00
impl < N : Scalar , D : DimName > Serialize for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
2018-09-13 12:55:58 +08:00
Owned < N , D , D > : Serialize ,
2018-02-02 19:26:35 +08:00
{
2017-08-03 01:37:44 +08:00
fn serialize < S > ( & self , serializer : S ) -> Result < S ::Ok , S ::Error >
2020-04-06 00:49:48 +08:00
where
S : Serializer ,
{
2018-02-02 19:26:35 +08:00
self . matrix . serialize ( serializer )
}
2017-08-03 01:37:44 +08:00
}
#[ cfg(feature = " serde-serialize " ) ]
2019-12-17 07:09:14 +08:00
impl < ' a , N : Scalar , D : DimName > Deserialize < ' a > for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
2018-09-13 12:55:58 +08:00
Owned < N , D , D > : Deserialize < ' a > ,
2018-02-02 19:26:35 +08:00
{
2017-08-03 01:37:44 +08:00
fn deserialize < Des > ( deserializer : Des ) -> Result < Self , Des ::Error >
2020-04-06 00:49:48 +08:00
where
Des : Deserializer < ' a > ,
{
2018-02-02 19:26:35 +08:00
let matrix = MatrixN ::< N , D > ::deserialize ( deserializer ) ? ;
2017-08-03 01:37:44 +08:00
2019-02-17 05:29:41 +08:00
Ok ( Self ::from_matrix_unchecked ( matrix ) )
2018-02-02 19:26:35 +08:00
}
2017-08-03 01:37:44 +08:00
}
2020-11-21 18:21:47 +08:00
impl < N : Scalar , D : DimName > Rotation < N , D >
where
DefaultAllocator : Allocator < N , D , D > ,
{
/// Creates a new rotation from the given square matrix.
///
/// The matrix squareness is checked but not its orthonormality.
///
/// # Example
/// ```
/// # use nalgebra::{Rotation2, Rotation3, Matrix2, Matrix3};
/// # use std::f32;
/// let mat = Matrix3::new(0.8660254, -0.5, 0.0,
/// 0.5, 0.8660254, 0.0,
/// 0.0, 0.0, 1.0);
/// let rot = Rotation3::from_matrix_unchecked(mat);
///
/// assert_eq!(*rot.matrix(), mat);
///
///
/// let mat = Matrix2::new(0.8660254, -0.5,
/// 0.5, 0.8660254);
/// let rot = Rotation2::from_matrix_unchecked(mat);
///
/// assert_eq!(*rot.matrix(), mat);
/// ```
#[ inline ]
pub fn from_matrix_unchecked ( matrix : MatrixN < N , D > ) -> Self {
assert! (
matrix . is_square ( ) ,
" Unable to create a rotation from a non-square matrix. "
) ;
Self { matrix }
}
}
/// # Conversion to a matrix
2019-12-17 07:09:14 +08:00
impl < N : Scalar , D : DimName > Rotation < N , D >
2020-04-06 00:49:48 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
2018-02-02 19:26:35 +08:00
{
2016-12-05 05:44:42 +08:00
/// A reference to the underlying matrix representation of this rotation.
2018-11-03 20:35:56 +08:00
///
/// # Example
/// ```
/// # use nalgebra::{Rotation2, Rotation3, Vector3, Matrix2, Matrix3};
/// # use std::f32;
/// let rot = Rotation3::from_axis_angle(&Vector3::z_axis(), f32::consts::FRAC_PI_6);
/// let expected = Matrix3::new(0.8660254, -0.5, 0.0,
/// 0.5, 0.8660254, 0.0,
/// 0.0, 0.0, 1.0);
/// assert_eq!(*rot.matrix(), expected);
///
///
/// let rot = Rotation2::new(f32::consts::FRAC_PI_6);
/// let expected = Matrix2::new(0.8660254, -0.5,
/// 0.5, 0.8660254);
/// assert_eq!(*rot.matrix(), expected);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
2017-08-03 01:37:44 +08:00
pub fn matrix ( & self ) -> & MatrixN < N , D > {
2016-12-05 05:44:42 +08:00
& self . matrix
}
2018-11-03 20:35:56 +08:00
/// A mutable reference to the underlying matrix representation of this rotation.
#[ inline ]
#[ deprecated(note = " Use `.matrix_mut_unchecked()` instead. " ) ]
pub unsafe fn matrix_mut ( & mut self ) -> & mut MatrixN < N , D > {
& mut self . matrix
}
2016-12-05 05:44:42 +08:00
/// A mutable reference to the underlying matrix representation of this rotation.
///
2018-11-03 20:35:56 +08:00
/// This is suffixed by "_unchecked" because this allows the user to replace the matrix by another one that is
2016-12-05 05:44:42 +08:00
/// non-square, non-inversible, or non-orthonormal. If one of those properties is broken,
/// subsequent method calls may be UB.
#[ inline ]
2018-11-03 20:35:56 +08:00
pub fn matrix_mut_unchecked ( & mut self ) -> & mut MatrixN < N , D > {
2016-12-05 05:44:42 +08:00
& mut self . matrix
}
/// Unwraps the underlying matrix.
2018-11-03 20:35:56 +08:00
///
/// # Example
/// ```
/// # use nalgebra::{Rotation2, Rotation3, Vector3, Matrix2, Matrix3};
/// # use std::f32;
/// let rot = Rotation3::from_axis_angle(&Vector3::z_axis(), f32::consts::FRAC_PI_6);
2018-12-10 04:16:06 +08:00
/// let mat = rot.into_inner();
2018-11-03 20:35:56 +08:00
/// let expected = Matrix3::new(0.8660254, -0.5, 0.0,
/// 0.5, 0.8660254, 0.0,
/// 0.0, 0.0, 1.0);
/// assert_eq!(mat, expected);
///
///
/// let rot = Rotation2::new(f32::consts::FRAC_PI_6);
2018-12-10 04:16:06 +08:00
/// let mat = rot.into_inner();
2018-11-03 20:35:56 +08:00
/// let expected = Matrix2::new(0.8660254, -0.5,
/// 0.5, 0.8660254);
/// assert_eq!(mat, expected);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
2018-12-10 04:16:06 +08:00
pub fn into_inner ( self ) -> MatrixN < N , D > {
self . matrix
}
/// Unwraps the underlying matrix.
/// Deprecated: Use [Rotation::into_inner] instead.
2020-03-21 19:16:46 +08:00
#[ deprecated(note = " use `.into_inner()` instead " ) ]
2018-12-10 04:16:06 +08:00
#[ inline ]
2017-08-03 01:37:44 +08:00
pub fn unwrap ( self ) -> MatrixN < N , D > {
2016-12-05 05:44:42 +08:00
self . matrix
}
/// Converts this rotation into its equivalent homogeneous transformation matrix.
2018-11-03 20:35:56 +08:00
///
/// This is the same as `self.into()`.
///
/// # Example
/// ```
2018-11-05 17:15:49 +08:00
/// # use nalgebra::{Rotation2, Rotation3, Vector3, Matrix3, Matrix4};
2018-11-03 20:35:56 +08:00
/// # use std::f32;
/// let rot = Rotation3::from_axis_angle(&Vector3::z_axis(), f32::consts::FRAC_PI_6);
/// let expected = Matrix4::new(0.8660254, -0.5, 0.0, 0.0,
/// 0.5, 0.8660254, 0.0, 0.0,
/// 0.0, 0.0, 1.0, 0.0,
/// 0.0, 0.0, 0.0, 1.0);
/// assert_eq!(rot.to_homogeneous(), expected);
///
///
/// let rot = Rotation2::new(f32::consts::FRAC_PI_6);
/// let expected = Matrix3::new(0.8660254, -0.5, 0.0,
/// 0.5, 0.8660254, 0.0,
/// 0.0, 0.0, 1.0);
/// assert_eq!(rot.to_homogeneous(), expected);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
2017-08-03 01:37:44 +08:00
pub fn to_homogeneous ( & self ) -> MatrixN < N , DimNameSum < D , U1 > >
2018-02-02 19:26:35 +08:00
where
N : Zero + One ,
D : DimNameAdd < U1 > ,
DefaultAllocator : Allocator < N , DimNameSum < D , U1 > , DimNameSum < D , U1 > > ,
{
2018-11-20 16:22:01 +08:00
// We could use `MatrixN::to_homogeneous()` here, but that would imply
// adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe
// these things will get nicer once specialization lands in Rust.
2017-08-03 01:37:44 +08:00
let mut res = MatrixN ::< N , DimNameSum < D , U1 > > ::identity ( ) ;
2016-12-05 05:44:42 +08:00
res . fixed_slice_mut ::< D , D > ( 0 , 0 ) . copy_from ( & self . matrix ) ;
res
}
2020-11-21 18:21:47 +08:00
}
2016-12-05 05:44:42 +08:00
2020-11-21 18:21:47 +08:00
/// # Transposition and inversion
impl < N : Scalar , D : DimName > Rotation < N , D >
where
DefaultAllocator : Allocator < N , D , D > ,
{
2016-12-05 05:44:42 +08:00
/// Transposes `self`.
2018-11-04 14:17:24 +08:00
///
/// Same as `.inverse()` because the inverse of a rotation matrix is its transform.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::{Rotation2, Rotation3, Vector3};
/// let rot = Rotation3::new(Vector3::new(1.0, 2.0, 3.0));
/// let tr_rot = rot.transpose();
/// assert_relative_eq!(rot * tr_rot, Rotation3::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(tr_rot * rot, Rotation3::identity(), epsilon = 1.0e-6);
///
/// let rot = Rotation2::new(1.2);
/// let tr_rot = rot.transpose();
/// assert_relative_eq!(rot * tr_rot, Rotation2::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(tr_rot * rot, Rotation2::identity(), epsilon = 1.0e-6);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
2019-06-06 05:04:04 +08:00
#[ must_use = " Did you mean to use transpose_mut()? " ]
2019-02-17 05:29:41 +08:00
pub fn transpose ( & self ) -> Self {
Self ::from_matrix_unchecked ( self . matrix . transpose ( ) )
2016-12-05 05:44:42 +08:00
}
/// Inverts `self`.
2018-11-03 20:35:56 +08:00
///
2018-11-04 14:17:24 +08:00
/// Same as `.transpose()` because the inverse of a rotation matrix is its transform.
///
2018-11-03 20:35:56 +08:00
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::{Rotation2, Rotation3, Vector3};
/// let rot = Rotation3::new(Vector3::new(1.0, 2.0, 3.0));
/// let inv = rot.inverse();
/// assert_relative_eq!(rot * inv, Rotation3::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(inv * rot, Rotation3::identity(), epsilon = 1.0e-6);
///
/// let rot = Rotation2::new(1.2);
/// let inv = rot.inverse();
/// assert_relative_eq!(rot * inv, Rotation2::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(inv * rot, Rotation2::identity(), epsilon = 1.0e-6);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
2019-06-06 05:04:04 +08:00
#[ must_use = " Did you mean to use inverse_mut()? " ]
2019-02-17 05:29:41 +08:00
pub fn inverse ( & self ) -> Self {
2016-12-05 05:44:42 +08:00
self . transpose ( )
}
/// Transposes `self` in-place.
2018-11-04 14:17:24 +08:00
///
/// Same as `.inverse_mut()` because the inverse of a rotation matrix is its transform.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::{Rotation2, Rotation3, Vector3};
/// let rot = Rotation3::new(Vector3::new(1.0, 2.0, 3.0));
/// let mut tr_rot = Rotation3::new(Vector3::new(1.0, 2.0, 3.0));
/// tr_rot.transpose_mut();
///
/// assert_relative_eq!(rot * tr_rot, Rotation3::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(tr_rot * rot, Rotation3::identity(), epsilon = 1.0e-6);
///
/// let rot = Rotation2::new(1.2);
/// let mut tr_rot = Rotation2::new(1.2);
/// tr_rot.transpose_mut();
///
/// assert_relative_eq!(rot * tr_rot, Rotation2::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(tr_rot * rot, Rotation2::identity(), epsilon = 1.0e-6);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
pub fn transpose_mut ( & mut self ) {
self . matrix . transpose_mut ( )
}
/// Inverts `self` in-place.
2018-11-04 14:17:24 +08:00
///
/// Same as `.transpose_mut()` because the inverse of a rotation matrix is its transform.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::{Rotation2, Rotation3, Vector3};
/// let rot = Rotation3::new(Vector3::new(1.0, 2.0, 3.0));
/// let mut inv = Rotation3::new(Vector3::new(1.0, 2.0, 3.0));
/// inv.inverse_mut();
///
/// assert_relative_eq!(rot * inv, Rotation3::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(inv * rot, Rotation3::identity(), epsilon = 1.0e-6);
///
/// let rot = Rotation2::new(1.2);
/// let mut inv = Rotation2::new(1.2);
/// inv.inverse_mut();
///
/// assert_relative_eq!(rot * inv, Rotation2::identity(), epsilon = 1.0e-6);
/// assert_relative_eq!(inv * rot, Rotation2::identity(), epsilon = 1.0e-6);
/// ```
2016-12-05 05:44:42 +08:00
#[ inline ]
pub fn inverse_mut ( & mut self ) {
self . transpose_mut ( )
}
}
2020-11-21 18:21:47 +08:00
/// # Transformation of a vector or a point
2020-03-22 06:22:55 +08:00
impl < N : SimdRealField , D : DimName > Rotation < N , D >
where
N ::Element : SimdRealField ,
DefaultAllocator : Allocator < N , D , D > + Allocator < N , D > ,
2019-02-25 00:29:27 +08:00
{
/// Rotate the given point.
///
2019-03-15 22:50:47 +08:00
/// This is the same as the multiplication `self * pt`.
///
2019-02-25 00:29:27 +08:00
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use std::f32;
/// # use nalgebra::{Point3, Rotation2, Rotation3, UnitQuaternion, Vector3};
/// let rot = Rotation3::new(Vector3::y() * f32::consts::FRAC_PI_2);
/// let transformed_point = rot.transform_point(&Point3::new(1.0, 2.0, 3.0));
///
/// assert_relative_eq!(transformed_point, Point3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
/// ```
#[ inline ]
pub fn transform_point ( & self , pt : & Point < N , D > ) -> Point < N , D > {
self * pt
}
/// Rotate the given vector.
///
2019-03-15 22:50:47 +08:00
/// This is the same as the multiplication `self * v`.
///
2019-02-25 00:29:27 +08:00
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use std::f32;
/// # use nalgebra::{Rotation2, Rotation3, UnitQuaternion, Vector3};
/// let rot = Rotation3::new(Vector3::y() * f32::consts::FRAC_PI_2);
/// let transformed_vector = rot.transform_vector(&Vector3::new(1.0, 2.0, 3.0));
///
/// assert_relative_eq!(transformed_vector, Vector3::new(3.0, 2.0, -1.0), epsilon = 1.0e-6);
/// ```
#[ inline ]
pub fn transform_vector ( & self , v : & VectorN < N , D > ) -> VectorN < N , D > {
self * v
}
/// Rotate the given point by the inverse of this rotation. This may be
/// cheaper than inverting the rotation and then transforming the given
/// point.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use std::f32;
/// # use nalgebra::{Point3, Rotation2, Rotation3, UnitQuaternion, Vector3};
/// let rot = Rotation3::new(Vector3::y() * f32::consts::FRAC_PI_2);
/// let transformed_point = rot.inverse_transform_point(&Point3::new(1.0, 2.0, 3.0));
///
/// assert_relative_eq!(transformed_point, Point3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
/// ```
#[ inline ]
pub fn inverse_transform_point ( & self , pt : & Point < N , D > ) -> Point < N , D > {
Point ::from ( self . inverse_transform_vector ( & pt . coords ) )
}
/// Rotate the given vector by the inverse of this rotation. This may be
/// cheaper than inverting the rotation and then transforming the given
/// vector.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use std::f32;
/// # use nalgebra::{Rotation2, Rotation3, UnitQuaternion, Vector3};
/// let rot = Rotation3::new(Vector3::y() * f32::consts::FRAC_PI_2);
/// let transformed_vector = rot.inverse_transform_vector(&Vector3::new(1.0, 2.0, 3.0));
///
/// assert_relative_eq!(transformed_vector, Vector3::new(-3.0, 2.0, 1.0), epsilon = 1.0e-6);
/// ```
#[ inline ]
pub fn inverse_transform_vector ( & self , v : & VectorN < N , D > ) -> VectorN < N , D > {
self . matrix ( ) . tr_mul ( v )
}
2020-10-25 18:23:34 +08:00
/// Rotate the given vector by the inverse of this rotation. This may be
/// cheaper than inverting the rotation and then transforming the given
/// vector.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use std::f32;
/// # use nalgebra::{Rotation2, Rotation3, UnitQuaternion, Vector3};
/// let rot = Rotation3::new(Vector3::z() * f32::consts::FRAC_PI_2);
/// let transformed_vector = rot.inverse_transform_unit_vector(&Vector3::x_axis());
///
/// assert_relative_eq!(transformed_vector, -Vector3::y_axis(), epsilon = 1.0e-6);
/// ```
#[ inline ]
pub fn inverse_transform_unit_vector ( & self , v : & Unit < VectorN < N , D > > ) -> Unit < VectorN < N , D > > {
Unit ::new_unchecked ( self . inverse_transform_vector ( & * * v ) )
}
2019-02-25 00:29:27 +08:00
}
2019-12-17 07:09:14 +08:00
impl < N : Scalar + Eq , D : DimName > Eq for Rotation < N , D > where DefaultAllocator : Allocator < N , D , D > { }
2016-12-05 05:44:42 +08:00
2019-12-17 07:09:14 +08:00
impl < N : Scalar + PartialEq , D : DimName > PartialEq for Rotation < N , D >
2020-04-06 00:49:48 +08:00
where
DefaultAllocator : Allocator < N , D , D > ,
2018-02-02 19:26:35 +08:00
{
2016-12-05 05:44:42 +08:00
#[ inline ]
2019-02-17 05:29:41 +08:00
fn eq ( & self , right : & Self ) -> bool {
2016-12-05 05:44:42 +08:00
self . matrix = = right . matrix
}
}
2018-05-19 21:41:58 +08:00
impl < N , D : DimName > AbsDiffEq for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
2019-12-17 07:09:14 +08:00
N : Scalar + AbsDiffEq ,
2018-02-02 19:26:35 +08:00
DefaultAllocator : Allocator < N , D , D > ,
N ::Epsilon : Copy ,
{
2016-12-05 05:44:42 +08:00
type Epsilon = N ::Epsilon ;
#[ inline ]
fn default_epsilon ( ) -> Self ::Epsilon {
N ::default_epsilon ( )
}
#[ inline ]
2018-05-19 21:41:58 +08:00
fn abs_diff_eq ( & self , other : & Self , epsilon : Self ::Epsilon ) -> bool {
self . matrix . abs_diff_eq ( & other . matrix , epsilon )
2016-12-05 05:44:42 +08:00
}
2018-05-19 21:41:58 +08:00
}
2016-12-05 05:44:42 +08:00
2018-05-19 21:41:58 +08:00
impl < N , D : DimName > RelativeEq for Rotation < N , D >
where
2019-12-17 07:09:14 +08:00
N : Scalar + RelativeEq ,
2018-05-19 21:41:58 +08:00
DefaultAllocator : Allocator < N , D , D > ,
N ::Epsilon : Copy ,
{
2016-12-05 05:44:42 +08:00
#[ inline ]
2018-05-19 21:41:58 +08:00
fn default_max_relative ( ) -> Self ::Epsilon {
N ::default_max_relative ( )
2016-12-05 05:44:42 +08:00
}
#[ inline ]
2018-02-02 19:26:35 +08:00
fn relative_eq (
& self ,
other : & Self ,
epsilon : Self ::Epsilon ,
max_relative : Self ::Epsilon ,
2020-04-06 00:49:48 +08:00
) -> bool {
2018-02-02 19:26:35 +08:00
self . matrix
. relative_eq ( & other . matrix , epsilon , max_relative )
2016-12-05 05:44:42 +08:00
}
2018-05-19 21:41:58 +08:00
}
impl < N , D : DimName > UlpsEq for Rotation < N , D >
where
2019-12-17 07:09:14 +08:00
N : Scalar + UlpsEq ,
2018-05-19 21:41:58 +08:00
DefaultAllocator : Allocator < N , D , D > ,
N ::Epsilon : Copy ,
{
#[ inline ]
fn default_max_ulps ( ) -> u32 {
N ::default_max_ulps ( )
}
2016-12-05 05:44:42 +08:00
#[ inline ]
fn ulps_eq ( & self , other : & Self , epsilon : Self ::Epsilon , max_ulps : u32 ) -> bool {
self . matrix . ulps_eq ( & other . matrix , epsilon , max_ulps )
}
}
/*
*
* Display
*
* /
2017-08-03 01:37:44 +08:00
impl < N , D : DimName > fmt ::Display for Rotation < N , D >
2018-02-02 19:26:35 +08:00
where
2019-03-25 18:21:41 +08:00
N : RealField + fmt ::Display ,
2018-02-02 19:26:35 +08:00
DefaultAllocator : Allocator < N , D , D > + Allocator < usize , D , D > ,
{
2016-12-05 05:44:42 +08:00
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
let precision = f . precision ( ) . unwrap_or ( 3 ) ;
2019-03-23 21:29:07 +08:00
writeln! ( f , " Rotation matrix {{ " ) ? ;
write! ( f , " {:.*} " , precision , self . matrix ) ? ;
2016-12-05 05:44:42 +08:00
writeln! ( f , " }} " )
}
}
// // /*
// // *
// // * Absolute
// // *
// // */
// // impl<N: Absolute> Absolute for $t<N> {
// // type AbsoluteValue = $submatrix<N::AbsoluteValue>;
// //
// // #[inline]
// // fn abs(m: &$t<N>) -> $submatrix<N::AbsoluteValue> {
// // Absolute::abs(&m.submatrix)
// // }
// // }