From c1372c3041eb5131b2a6538b83f4823ab437462e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crozet=20S=C3=A9bastien?= Date: Sat, 21 Nov 2020 11:56:24 +0100 Subject: [PATCH] Add sections to the UnitComplex documentation --- src/geometry/rotation.rs | 2 +- src/geometry/unit_complex.rs | 119 ++++++++++------------ src/geometry/unit_complex_construction.rs | 75 ++++++++++++++ 3 files changed, 129 insertions(+), 67 deletions(-) diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs index 20985093..e4f69fe6 100755 --- a/src/geometry/rotation.rs +++ b/src/geometry/rotation.rs @@ -50,7 +50,7 @@ use crate::geometry::Point; /// * [Transposition and inversion `transpose`, `inverse`…](#transposition-and-inversion) /// * [Interpolation `slerp`…](#interpolation) /// -/// # Conversion to a matrix +/// # Conversion /// * [Conversion to a matrix `matrix`, `to_homogeneous`…](#conversion-to-a-matrix) /// #[repr(C)] diff --git a/src/geometry/unit_complex.rs b/src/geometry/unit_complex.rs index 76d7f392..40148454 100755 --- a/src/geometry/unit_complex.rs +++ b/src/geometry/unit_complex.rs @@ -7,7 +7,26 @@ use crate::geometry::{Point2, Rotation2}; use simba::scalar::RealField; 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 `identity`](#identity) +/// * [From a 2D rotation angle `new`, `from_cos_sin_unchecked`…](#construction-from-a-2d-rotation-angle) +/// * [From an existing 2D matrix or complex number `from_matrix`, `rotation_to`, `powf`…](#construction-from-an-existing-2d-matrix-or-complex-number) +/// * [From two vectors `rotation_between`, `scaled_rotation_between_axis`…](#construction-from-two-vectors) +/// +/// # Transformation and composition +/// * [Angle extraction `angle`, `angle_to`…](#angle-extraction) +/// * [Transformation of a vector or a point `transform_vector`, `inverse_transform_point`…](#transformation-of-a-vector-or-a-point) +/// * [Conjugation and inversion `conjugate`, `inverse_mut`…](#conjugation-and-inversion) +/// * [Interpolation `slerp`…](#interpolation) +/// +/// # Conversion +/// * [Conversion to a matrix `to_rotation_matrix`, `to_homogeneous`…](#conversion-to-a-matrix) pub type UnitComplex = Unit>; impl Normed for Complex { @@ -40,6 +59,7 @@ impl Normed for Complex { } } +/// # Angle extraction impl UnitComplex where N::Element: SimdRealField, @@ -115,24 +135,28 @@ where } } - /// The underlying complex number. - /// - /// Same as `self.as_ref()`. + /// The rotation angle needed to make `self` and `other` coincide. /// /// # Example /// ``` - /// # extern crate num_complex; - /// # use num_complex::Complex; + /// # #[macro_use] extern crate approx; /// # use nalgebra::UnitComplex; - /// let angle = 1.78f32; - /// let rot = UnitComplex::new(angle); - /// assert_eq!(*rot.complex(), Complex::new(angle.cos(), angle.sin())); + /// let rot1 = UnitComplex::new(0.1); + /// let rot2 = UnitComplex::new(1.7); + /// assert_relative_eq!(rot1.angle_to(&rot2), 1.6); /// ``` #[inline] - pub fn complex(&self) -> &Complex { - self.as_ref() + pub fn angle_to(&self, other: &Self) -> N { + let delta = self.rotation_to(other); + delta.angle() } +} +/// # Conjugation and inversion +impl UnitComplex +where + N::Element: SimdRealField, +{ /// Compute the conjugate of this unit complex number. /// /// # Example @@ -166,42 +190,6 @@ where 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. /// /// # Example @@ -237,25 +225,13 @@ where pub fn inverse_mut(&mut self) { 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 UnitComplex +where + N::Element: SimdRealField, +{ /// Builds the rotation matrix corresponding to this unit complex number. /// /// # Example @@ -290,7 +266,13 @@ where pub fn to_homogeneous(&self) -> Matrix3 { self.to_rotation_matrix().to_homogeneous() } +} +/// # Transformation of a vector or a point +impl UnitComplex +where + N::Element: SimdRealField, +{ /// Rotate the given point by this unit complex number. /// /// This is the same as the multiplication `self * pt`. @@ -376,7 +358,13 @@ where pub fn inverse_transform_unit_vector(&self, v: &Unit>) -> Unit> { self.inverse() * v } +} +/// # Interpolation +impl UnitComplex +where + N::Element: SimdRealField, +{ /// Spherical linear interpolation between two rotations represented as unit complex numbers. /// /// # Examples: @@ -392,7 +380,6 @@ where /// /// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2); /// ``` - #[inline] pub fn slerp(&self, other: &Self, t: N) -> Self { Self::new(self.angle() * (N::one() - t) + other.angle() * t) diff --git a/src/geometry/unit_complex_construction.rs b/src/geometry/unit_complex_construction.rs index 826b5671..65d36888 100644 --- a/src/geometry/unit_complex_construction.rs +++ b/src/geometry/unit_complex_construction.rs @@ -13,6 +13,7 @@ use crate::geometry::{Rotation2, UnitComplex}; use simba::scalar::RealField; use simba::simd::SimdRealField; +/// # Identity impl UnitComplex where N::Element: SimdRealField, @@ -32,7 +33,13 @@ where pub fn identity() -> Self { Self::new_unchecked(Complex::new(N::one(), N::zero())) } +} +/// # Construction from a 2D rotation angle +impl UnitComplex +where + N::Element: SimdRealField, +{ /// Builds the unit complex number corresponding to the rotation with the given angle. /// /// # Example @@ -100,6 +107,30 @@ where pub fn from_scaled_axis>(axisangle: Vector) -> Self { Self::from_angle(axisangle[0]) } +} + +/// # Construction from an existing 2D matrix or complex number +impl UnitComplex +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 { + self.as_ref() + } /// 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() } + /// 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 UnitComplex +where + N::Element: SimdRealField, +{ /// The unit complex needed to make `a` and `b` be collinear and point toward the same /// direction. ///