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 ;
2016-12-05 05:44:42 +08:00
2021-04-12 18:14:16 +08:00
#[ cfg(feature = " serde-serialize-no-std " ) ]
2018-10-22 13:00:10 +08:00
use serde ::{ Deserialize , Deserializer , Serialize , Serializer } ;
2017-08-03 01:37:44 +08:00
2021-04-12 18:14:16 +08:00
#[ cfg(feature = " serde-serialize-no-std " ) ]
2021-08-03 00:41:46 +08:00
use crate ::base ::storage ::Owned ;
2017-05-04 10:02:30 +08:00
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 ;
2021-04-07 20:29:20 +08:00
use crate ::base ::dimension ::{ DimNameAdd , DimNameSum , U1 } ;
2021-04-11 17:00:38 +08:00
use crate ::base ::{ Const , DefaultAllocator , OMatrix , SMatrix , SVector , Scalar , Unit } ;
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)
///
2021-08-03 00:41:46 +08:00
#[ repr(C) ]
2022-04-30 16:32:10 +08:00
#[ cfg_attr(
feature = " rkyv-serialize-no-std " ,
derive ( rkyv ::Archive , rkyv ::Serialize , rkyv ::Deserialize )
) ]
2022-09-15 16:40:16 +08:00
#[ cfg_attr(
feature = " rkyv-serialize " ,
archive_attr ( derive ( bytecheck ::CheckBytes ) )
) ]
2022-03-17 01:07:29 +08:00
#[ cfg_attr(feature = " cuda " , derive(cust_core::DeviceCopy)) ]
2021-11-23 19:03:11 +08:00
#[ derive(Copy, Clone) ]
2021-07-06 08:04:10 +08:00
pub struct Rotation < T , const D : usize > {
2021-04-11 17:00:38 +08:00
matrix : SMatrix < T , D , D > ,
2016-12-05 05:44:42 +08:00
}
2021-09-13 01:52:46 +08:00
impl < T : fmt ::Debug , const D : usize > fmt ::Debug for Rotation < T , D > {
fn fmt ( & self , formatter : & mut fmt ::Formatter < '_ > ) -> Result < ( ) , fmt ::Error > {
self . matrix . fmt ( formatter )
}
}
2021-08-03 00:41:46 +08:00
impl < T : Scalar + hash ::Hash , const D : usize > hash ::Hash for Rotation < T , D >
2018-02-02 19:26:35 +08:00
where
2021-08-03 00:41:46 +08:00
< DefaultAllocator as Allocator < T , Const < D > , Const < D > > > ::Buffer : hash ::Hash ,
2018-02-02 19:26:35 +08:00
{
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
}
}
2021-06-29 09:36:28 +08:00
#[ cfg(feature = " bytemuck " ) ]
unsafe impl < T , const D : usize > bytemuck ::Zeroable for Rotation < T , D >
where
2021-07-10 04:23:08 +08:00
T : Scalar + bytemuck ::Zeroable ,
2021-06-29 09:36:28 +08:00
SMatrix < T , D , D > : bytemuck ::Zeroable ,
{
}
#[ cfg(feature = " bytemuck " ) ]
unsafe impl < T , const D : usize > bytemuck ::Pod for Rotation < T , D >
where
2021-07-10 04:23:08 +08:00
T : Scalar + bytemuck ::Pod ,
2021-06-29 09:36:28 +08:00
SMatrix < T , D , D > : bytemuck ::Pod ,
{
}
2021-04-12 18:14:16 +08:00
#[ cfg(feature = " serde-serialize-no-std " ) ]
2021-04-11 17:00:38 +08:00
impl < T : Scalar , const D : usize > Serialize for Rotation < T , D >
2018-02-02 19:26:35 +08:00
where
2021-08-03 00:41:46 +08:00
Owned < T , Const < D > , Const < 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
}
2021-04-12 18:14:16 +08:00
#[ cfg(feature = " serde-serialize-no-std " ) ]
2021-08-03 00:41:46 +08:00
impl < ' a , T : Scalar , const D : usize > Deserialize < ' a > for Rotation < T , D >
2018-02-02 19:26:35 +08:00
where
2021-08-03 00:41:46 +08:00
Owned < T , Const < D > , Const < 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 > ,
{
2021-04-11 17:00:38 +08:00
let matrix = SMatrix ::< T , D , 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
}
2021-07-17 12:17:56 +08:00
impl < T , const D : usize > Rotation < T , D > {
2020-11-21 18:21:47 +08:00
/// Creates a new rotation from the given square matrix.
///
2021-07-23 07:07:12 +08:00
/// The matrix orthonormality is not checked.
2020-11-21 18:21:47 +08:00
///
/// # 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 ]
2021-07-23 07:07:12 +08:00
pub const fn from_matrix_unchecked ( matrix : SMatrix < T , D , D > ) -> Self {
2020-11-21 18:21:47 +08:00
Self { matrix }
}
}
/// # Conversion to a matrix
2021-08-03 00:41:46 +08:00
impl < T : Scalar , const D : usize > Rotation < T , D > {
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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn matrix ( & self ) -> & SMatrix < T , D , 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. " ) ]
2021-08-03 00:41:46 +08:00
pub unsafe fn matrix_mut ( & mut self ) -> & mut SMatrix < T , D , D > {
2018-11-03 20:35:56 +08:00
& mut self . matrix
}
2016-12-05 05:44:42 +08:00
/// A mutable reference to the underlying matrix representation of this rotation.
///
2021-07-06 07:53:11 +08:00
/// This is suffixed by "_unchecked" because this allows the user to replace the
/// matrix by another one that is non-inversible or non-orthonormal. If one of
/// those properties is broken, subsequent method calls may return bogus results.
2016-12-05 05:44:42 +08:00
#[ inline ]
2021-04-11 17:00:38 +08:00
pub fn matrix_mut_unchecked ( & mut self ) -> & mut SMatrix < T , D , 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 ]
2021-04-11 17:00:38 +08:00
pub fn into_inner ( self ) -> SMatrix < T , D , D > {
2018-12-10 04:16:06 +08:00
self . matrix
}
/// Unwraps the underlying matrix.
2021-07-28 07:18:29 +08:00
/// 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 ]
2021-04-11 17:00:38 +08:00
pub fn unwrap ( self ) -> SMatrix < T , D , 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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn to_homogeneous ( & self ) -> OMatrix < T , DimNameSum < Const < D > , U1 > , DimNameSum < Const < D > , U1 > >
2018-02-02 19:26:35 +08:00
where
2021-08-03 00:41:46 +08:00
T : Zero + One ,
2021-04-07 20:29:20 +08:00
Const < D > : DimNameAdd < U1 > ,
2021-04-11 17:00:38 +08:00
DefaultAllocator : Allocator < T , DimNameSum < Const < D > , U1 > , DimNameSum < Const < D > , U1 > > ,
2018-02-02 19:26:35 +08:00
{
2021-04-11 17:00:38 +08:00
// We could use `SMatrix::to_homogeneous()` here, but that would imply
2018-11-20 16:22:01 +08:00
// adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe
// these things will get nicer once specialization lands in Rust.
2021-04-11 17:00:38 +08:00
let mut res = OMatrix ::< T , DimNameSum < Const < D > , U1 > , DimNameSum < Const < D > , U1 > > ::identity ( ) ;
res . fixed_slice_mut ::< D , D > ( 0 , 0 ) . copy_from ( & self . matrix ) ;
2016-12-05 05:44:42 +08:00
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
2021-04-11 17:00:38 +08:00
impl < T : Scalar , const D : usize > Rotation < T , 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
2021-04-11 17:00:38 +08:00
impl < T : SimdRealField , const D : usize > Rotation < T , D >
2020-03-22 06:22:55 +08:00
where
2021-04-11 17:00:38 +08:00
T ::Element : SimdRealField ,
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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn transform_point ( & self , pt : & Point < T , D > ) -> Point < T , D > {
2019-02-25 00:29:27 +08:00
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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn transform_vector ( & self , v : & SVector < T , D > ) -> SVector < T , D > {
2019-02-25 00:29:27 +08:00
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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn inverse_transform_point ( & self , pt : & Point < T , D > ) -> Point < T , D > {
2019-02-25 00:29:27 +08:00
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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn inverse_transform_vector ( & self , v : & SVector < T , D > ) -> SVector < T , D > {
2019-02-25 00:29:27 +08:00
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 ]
2021-06-07 22:34:03 +08:00
#[ must_use ]
2021-04-11 17:00:38 +08:00
pub fn inverse_transform_unit_vector ( & self , v : & Unit < SVector < T , D > > ) -> Unit < SVector < T , D > > {
2020-10-25 18:23:34 +08:00
Unit ::new_unchecked ( self . inverse_transform_vector ( & * * v ) )
}
2019-02-25 00:29:27 +08:00
}
2021-04-11 17:00:38 +08:00
impl < T : Scalar + Eq , const D : usize > Eq for Rotation < T , D > { }
2016-12-05 05:44:42 +08:00
2021-04-11 17:00:38 +08:00
impl < T : Scalar + PartialEq , const D : usize > PartialEq for Rotation < T , D > {
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
}
}
2021-04-11 17:00:38 +08:00
impl < T , const D : usize > AbsDiffEq for Rotation < T , D >
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T : Scalar + AbsDiffEq ,
2021-08-04 23:34:25 +08:00
T ::Epsilon : Clone ,
2018-02-02 19:26:35 +08:00
{
2021-04-11 17:00:38 +08:00
type Epsilon = T ::Epsilon ;
2016-12-05 05:44:42 +08:00
#[ inline ]
fn default_epsilon ( ) -> Self ::Epsilon {
2021-04-11 17:00:38 +08:00
T ::default_epsilon ( )
2016-12-05 05:44:42 +08:00
}
#[ 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
2021-04-11 17:00:38 +08:00
impl < T , const D : usize > RelativeEq for Rotation < T , D >
2018-05-19 21:41:58 +08:00
where
2021-04-11 17:00:38 +08:00
T : Scalar + RelativeEq ,
2021-08-04 23:34:25 +08:00
T ::Epsilon : Clone ,
2018-05-19 21:41:58 +08:00
{
2016-12-05 05:44:42 +08:00
#[ inline ]
2018-05-19 21:41:58 +08:00
fn default_max_relative ( ) -> Self ::Epsilon {
2021-04-11 17:00:38 +08:00
T ::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
}
2021-04-11 17:00:38 +08:00
impl < T , const D : usize > UlpsEq for Rotation < T , D >
2018-05-19 21:41:58 +08:00
where
2021-04-11 17:00:38 +08:00
T : Scalar + UlpsEq ,
2021-08-04 23:34:25 +08:00
T ::Epsilon : Clone ,
2018-05-19 21:41:58 +08:00
{
#[ inline ]
fn default_max_ulps ( ) -> u32 {
2021-04-11 17:00:38 +08:00
T ::default_max_ulps ( )
2018-05-19 21:41:58 +08:00
}
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
*
* /
2021-04-11 17:00:38 +08:00
impl < T , const D : usize > fmt ::Display for Rotation < T , D >
2018-02-02 19:26:35 +08:00
where
2021-04-11 17:00:38 +08:00
T : RealField + fmt ::Display ,
2018-02-02 19:26:35 +08:00
{
2021-07-26 01:06:14 +08:00
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
2016-12-05 05:44:42 +08:00
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
// // *
// // */
2021-04-11 17:00:38 +08:00
// // impl<T: Absolute> Absolute for $t<T> {
// // type AbsoluteValue = $submatrix<T::AbsoluteValue>;
2016-12-05 05:44:42 +08:00
// //
// // #[inline]
2021-04-11 17:00:38 +08:00
// // fn abs(m: &$t<T>) -> $submatrix<T::AbsoluteValue> {
2016-12-05 05:44:42 +08:00
// // Absolute::abs(&m.submatrix)
// // }
// // }