Add sections to the UnitComplex documentation

This commit is contained in:
Crozet Sébastien 2020-11-21 11:56:24 +01:00
parent 99ac7a8e08
commit c1372c3041
3 changed files with 129 additions and 67 deletions

View File

@ -50,7 +50,7 @@ use crate::geometry::Point;
/// * [Transposition and inversion <span style="float:right;">`transpose`, `inverse`…</span>](#transposition-and-inversion) /// * [Transposition and inversion <span style="float:right;">`transpose`, `inverse`…</span>](#transposition-and-inversion)
/// * [Interpolation <span style="float:right;">`slerp`…</span>](#interpolation) /// * [Interpolation <span style="float:right;">`slerp`…</span>](#interpolation)
/// ///
/// # Conversion to a matrix /// # Conversion
/// * [Conversion to a matrix <span style="float:right;">`matrix`, `to_homogeneous`…</span>](#conversion-to-a-matrix) /// * [Conversion to a matrix <span style="float:right;">`matrix`, `to_homogeneous`…</span>](#conversion-to-a-matrix)
/// ///
#[repr(C)] #[repr(C)]

View File

@ -7,7 +7,26 @@ use crate::geometry::{Point2, Rotation2};
use simba::scalar::RealField; use simba::scalar::RealField;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
/// A complex number with a norm equal to 1. /// A 2D rotation represented as a complex number with magnitude 1.
///
/// All the methods specific [`UnitComplex`](crate::UnitComplex) are listed here. You may also
/// read the documentation of the [`Complex`](crate::Complex) type which
/// is used internally and accessible with `unit_complex.complex()`.
///
/// # Construction
/// * [Identity <span style="float:right;">`identity`</span>](#identity)
/// * [From a 2D rotation angle <span style="float:right;">`new`, `from_cos_sin_unchecked`…</span>](#construction-from-a-2d-rotation-angle)
/// * [From an existing 2D matrix or complex number <span style="float:right;">`from_matrix`, `rotation_to`, `powf`…</span>](#construction-from-an-existing-2d-matrix-or-complex-number)
/// * [From two vectors <span style="float:right;">`rotation_between`, `scaled_rotation_between_axis`…</span>](#construction-from-two-vectors)
///
/// # Transformation and composition
/// * [Angle extraction <span style="float:right;">`angle`, `angle_to`…</span>](#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)
/// * [Conjugation and inversion <span style="float:right;">`conjugate`, `inverse_mut`…</span>](#conjugation-and-inversion)
/// * [Interpolation <span style="float:right;">`slerp`…</span>](#interpolation)
///
/// # Conversion
/// * [Conversion to a matrix <span style="float:right;">`to_rotation_matrix`, `to_homogeneous`…</span>](#conversion-to-a-matrix)
pub type UnitComplex<N> = Unit<Complex<N>>; pub type UnitComplex<N> = Unit<Complex<N>>;
impl<N: SimdRealField> Normed for Complex<N> { impl<N: SimdRealField> Normed for Complex<N> {
@ -40,6 +59,7 @@ impl<N: SimdRealField> Normed for Complex<N> {
} }
} }
/// # Angle extraction
impl<N: SimdRealField> UnitComplex<N> impl<N: SimdRealField> UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
@ -115,24 +135,28 @@ where
} }
} }
/// The underlying complex number. /// The rotation angle needed to make `self` and `other` coincide.
///
/// Same as `self.as_ref()`.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # extern crate num_complex; /// # #[macro_use] extern crate approx;
/// # use num_complex::Complex;
/// # use nalgebra::UnitComplex; /// # use nalgebra::UnitComplex;
/// let angle = 1.78f32; /// let rot1 = UnitComplex::new(0.1);
/// let rot = UnitComplex::new(angle); /// let rot2 = UnitComplex::new(1.7);
/// assert_eq!(*rot.complex(), Complex::new(angle.cos(), angle.sin())); /// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
/// ``` /// ```
#[inline] #[inline]
pub fn complex(&self) -> &Complex<N> { pub fn angle_to(&self, other: &Self) -> N {
self.as_ref() let delta = self.rotation_to(other);
delta.angle()
}
} }
/// # Conjugation and inversion
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// Compute the conjugate of this unit complex number. /// Compute the conjugate of this unit complex number.
/// ///
/// # Example /// # Example
@ -166,42 +190,6 @@ where
self.conjugate() self.conjugate()
} }
/// The rotation angle needed to make `self` and `other` coincide.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::UnitComplex;
/// let rot1 = UnitComplex::new(0.1);
/// let rot2 = UnitComplex::new(1.7);
/// assert_relative_eq!(rot1.angle_to(&rot2), 1.6);
/// ```
#[inline]
pub fn angle_to(&self, other: &Self) -> N {
let delta = self.rotation_to(other);
delta.angle()
}
/// The unit complex number needed to make `self` and `other` coincide.
///
/// The result is such that: `self.rotation_to(other) * self == other`.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::UnitComplex;
/// let rot1 = UnitComplex::new(0.1);
/// let rot2 = UnitComplex::new(1.7);
/// let rot_to = rot1.rotation_to(&rot2);
///
/// assert_relative_eq!(rot_to * rot1, rot2);
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
/// ```
#[inline]
pub fn rotation_to(&self, other: &Self) -> Self {
other / self
}
/// Compute in-place the conjugate of this unit complex number. /// Compute in-place the conjugate of this unit complex number.
/// ///
/// # Example /// # Example
@ -237,25 +225,13 @@ where
pub fn inverse_mut(&mut self) { pub fn inverse_mut(&mut self) {
self.conjugate_mut() self.conjugate_mut()
} }
/// Raise this unit complex number to a given floating power.
///
/// This returns the unit complex number that identifies a rotation angle equal to
/// `self.angle() × n`.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::UnitComplex;
/// let rot = UnitComplex::new(0.78);
/// let pow = rot.powf(2.0);
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
/// ```
#[inline]
pub fn powf(&self, n: N) -> Self {
Self::from_angle(self.angle() * n)
} }
/// # Conversion to a matrix
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// Builds the rotation matrix corresponding to this unit complex number. /// Builds the rotation matrix corresponding to this unit complex number.
/// ///
/// # Example /// # Example
@ -290,7 +266,13 @@ where
pub fn to_homogeneous(&self) -> Matrix3<N> { pub fn to_homogeneous(&self) -> Matrix3<N> {
self.to_rotation_matrix().to_homogeneous() self.to_rotation_matrix().to_homogeneous()
} }
}
/// # Transformation of a vector or a point
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// Rotate the given point by this unit complex number. /// Rotate the given point by this unit complex number.
/// ///
/// This is the same as the multiplication `self * pt`. /// This is the same as the multiplication `self * pt`.
@ -376,7 +358,13 @@ where
pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector2<N>>) -> Unit<Vector2<N>> { pub fn inverse_transform_unit_vector(&self, v: &Unit<Vector2<N>>) -> Unit<Vector2<N>> {
self.inverse() * v self.inverse() * v
} }
}
/// # Interpolation
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// Spherical linear interpolation between two rotations represented as unit complex numbers. /// Spherical linear interpolation between two rotations represented as unit complex numbers.
/// ///
/// # Examples: /// # Examples:
@ -392,7 +380,6 @@ where
/// ///
/// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2); /// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
/// ``` /// ```
#[inline] #[inline]
pub fn slerp(&self, other: &Self, t: N) -> Self { pub fn slerp(&self, other: &Self, t: N) -> Self {
Self::new(self.angle() * (N::one() - t) + other.angle() * t) Self::new(self.angle() * (N::one() - t) + other.angle() * t)

View File

@ -13,6 +13,7 @@ use crate::geometry::{Rotation2, UnitComplex};
use simba::scalar::RealField; use simba::scalar::RealField;
use simba::simd::SimdRealField; use simba::simd::SimdRealField;
/// # Identity
impl<N: SimdRealField> UnitComplex<N> impl<N: SimdRealField> UnitComplex<N>
where where
N::Element: SimdRealField, N::Element: SimdRealField,
@ -32,7 +33,13 @@ where
pub fn identity() -> Self { pub fn identity() -> Self {
Self::new_unchecked(Complex::new(N::one(), N::zero())) Self::new_unchecked(Complex::new(N::one(), N::zero()))
} }
}
/// # Construction from a 2D rotation angle
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// Builds the unit complex number corresponding to the rotation with the given angle. /// Builds the unit complex number corresponding to the rotation with the given angle.
/// ///
/// # Example /// # Example
@ -100,6 +107,30 @@ where
pub fn from_scaled_axis<SB: Storage<N, U1>>(axisangle: Vector<N, U1, SB>) -> Self { pub fn from_scaled_axis<SB: Storage<N, U1>>(axisangle: Vector<N, U1, SB>) -> Self {
Self::from_angle(axisangle[0]) Self::from_angle(axisangle[0])
} }
}
/// # Construction from an existing 2D matrix or complex number
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// The underlying complex number.
///
/// Same as `self.as_ref()`.
///
/// # Example
/// ```
/// # extern crate num_complex;
/// # use num_complex::Complex;
/// # use nalgebra::UnitComplex;
/// let angle = 1.78f32;
/// let rot = UnitComplex::new(angle);
/// assert_eq!(*rot.complex(), Complex::new(angle.cos(), angle.sin()));
/// ```
#[inline]
pub fn complex(&self) -> &Complex<N> {
self.as_ref()
}
/// Creates a new unit complex number from a complex number. /// Creates a new unit complex number from a complex number.
/// ///
@ -165,6 +196,50 @@ where
Rotation2::from_matrix_eps(m, eps, max_iter, guess).into() Rotation2::from_matrix_eps(m, eps, max_iter, guess).into()
} }
/// The unit complex number needed to make `self` and `other` coincide.
///
/// The result is such that: `self.rotation_to(other) * self == other`.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::UnitComplex;
/// let rot1 = UnitComplex::new(0.1);
/// let rot2 = UnitComplex::new(1.7);
/// let rot_to = rot1.rotation_to(&rot2);
///
/// assert_relative_eq!(rot_to * rot1, rot2);
/// assert_relative_eq!(rot_to.inverse() * rot2, rot1);
/// ```
#[inline]
pub fn rotation_to(&self, other: &Self) -> Self {
other / self
}
/// Raise this unit complex number to a given floating power.
///
/// This returns the unit complex number that identifies a rotation angle equal to
/// `self.angle() × n`.
///
/// # Example
/// ```
/// # #[macro_use] extern crate approx;
/// # use nalgebra::UnitComplex;
/// let rot = UnitComplex::new(0.78);
/// let pow = rot.powf(2.0);
/// assert_relative_eq!(pow.angle(), 2.0 * 0.78);
/// ```
#[inline]
pub fn powf(&self, n: N) -> Self {
Self::from_angle(self.angle() * n)
}
}
/// # Construction from two vectors
impl<N: SimdRealField> UnitComplex<N>
where
N::Element: SimdRealField,
{
/// The unit complex needed to make `a` and `b` be collinear and point toward the same /// The unit complex needed to make `a` and `b` be collinear and point toward the same
/// direction. /// direction.
/// ///