Add inverse_transform_unit_vector to rotations and isometries.
This commit is contained in:
parent
eb94084760
commit
3d82c4335e
@ -1,6 +1,6 @@
|
||||
use crate::allocator::Allocator;
|
||||
use crate::geometry::{Rotation, UnitComplex, UnitQuaternion};
|
||||
use crate::{DefaultAllocator, DimName, Point, Scalar, SimdRealField, VectorN, U2, U3};
|
||||
use crate::{DefaultAllocator, DimName, Point, Scalar, SimdRealField, Unit, VectorN, U2, U3};
|
||||
|
||||
use simba::scalar::ClosedMul;
|
||||
|
||||
@ -24,6 +24,13 @@ pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone
|
||||
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
||||
where
|
||||
DefaultAllocator: Allocator<N, D>;
|
||||
/// Apply the inverse rotation to the given unit vector.
|
||||
fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>>
|
||||
where
|
||||
DefaultAllocator: Allocator<N, D>,
|
||||
{
|
||||
Unit::new_unchecked(self.inverse_transform_vector(&**v))
|
||||
}
|
||||
/// Apply the inverse rotation to the given point.
|
||||
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||
where
|
||||
@ -74,6 +81,14 @@ where
|
||||
self.inverse_transform_vector(v)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>>
|
||||
where
|
||||
DefaultAllocator: Allocator<N, D>,
|
||||
{
|
||||
self.inverse_transform_unit_vector(v)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||
where
|
||||
|
@ -16,7 +16,7 @@ use simba::simd::SimdRealField;
|
||||
use crate::base::allocator::Allocator;
|
||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
||||
use crate::base::storage::Owned;
|
||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN};
|
||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, Unit, VectorN};
|
||||
use crate::geometry::{AbstractRotation, Point, Translation};
|
||||
|
||||
/// A direct isometry, i.e., a rotation followed by a translation, aka. a rigid-body motion, aka. an element of a Special Euclidean (SE) group.
|
||||
@ -350,6 +350,29 @@ where
|
||||
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
||||
self.rotation.inverse_transform_vector(v)
|
||||
}
|
||||
|
||||
/// Transform the given unit vector by the inverse of this isometry, ignoring the
|
||||
/// translation component of the isometry. This may be
|
||||
/// less expensive than computing the entire isometry inverse and then
|
||||
/// transforming the point.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate approx;
|
||||
/// # use std::f32;
|
||||
/// # use nalgebra::{Isometry3, Translation3, UnitQuaternion, Vector3};
|
||||
/// let tra = Translation3::new(0.0, 0.0, 3.0);
|
||||
/// let rot = UnitQuaternion::from_scaled_axis(Vector3::z() * f32::consts::FRAC_PI_2);
|
||||
/// let iso = Isometry3::from_parts(tra, rot);
|
||||
///
|
||||
/// let transformed_point = iso.inverse_transform_unit_vector(&Vector3::x_axis());
|
||||
/// assert_relative_eq!(transformed_point, -Vector3::y_axis(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<VectorN<N, D>>) -> Unit<VectorN<N, D>> {
|
||||
self.rotation.inverse_transform_unit_vector(v)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: we don't require `R: Rotation<...>` here because this is not useful for the implementation
|
||||
|
@ -1542,6 +1542,26 @@ where
|
||||
pub fn inverse_transform_vector(&self, v: &Vector3<N>) -> Vector3<N> {
|
||||
self.inverse() * v
|
||||
}
|
||||
|
||||
/// Rotate a vector by the inverse of this unit quaternion. This may be
|
||||
/// cheaper than inverting the unit quaternion and transforming the
|
||||
/// vector.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate approx;
|
||||
/// # use std::f32;
|
||||
/// # use nalgebra::{UnitQuaternion, Vector3};
|
||||
/// let rot = UnitQuaternion::from_axis_angle(&Vector3::z_axis(), 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<Vector3<N>>) -> Unit<Vector3<N>> {
|
||||
self.inverse() * v
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: RealField> Default for UnitQuaternion<N> {
|
||||
|
@ -19,7 +19,7 @@ use simba::simd::SimdRealField;
|
||||
|
||||
use crate::base::allocator::Allocator;
|
||||
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
|
||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN};
|
||||
use crate::base::{DefaultAllocator, MatrixN, Scalar, Unit, VectorN};
|
||||
use crate::geometry::Point;
|
||||
|
||||
/// A rotation matrix.
|
||||
@ -441,6 +441,25 @@ where
|
||||
pub fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D> {
|
||||
self.matrix().tr_mul(v)
|
||||
}
|
||||
|
||||
/// 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))
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Scalar + Eq, D: DimName> Eq for Rotation<N, D> where DefaultAllocator: Allocator<N, D, D> {}
|
||||
|
@ -360,6 +360,22 @@ where
|
||||
pub fn inverse_transform_vector(&self, v: &Vector2<N>) -> Vector2<N> {
|
||||
self.inverse() * v
|
||||
}
|
||||
|
||||
/// Rotate the given vector by the inverse of this unit complex number.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # #[macro_use] extern crate approx;
|
||||
/// # use nalgebra::{UnitComplex, Vector2};
|
||||
/// # use std::f32;
|
||||
/// let rot = UnitComplex::new(f32::consts::FRAC_PI_2);
|
||||
/// let transformed_vector = rot.inverse_transform_unit_vector(&Vector2::x_axis());
|
||||
/// assert_relative_eq!(transformed_vector, -Vector2::y_axis(), epsilon = 1.0e-6);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector2<N>>) -> Unit<Vector2<N>> {
|
||||
self.inverse() * v
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: RealField + fmt::Display> fmt::Display for UnitComplex<N> {
|
||||
|
Loading…
Reference in New Issue
Block a user