rotation_interpolation.rs - source
Description: Source of the Rust file `/Users/erlendbasso/.cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.32.1/src/geometry/rotation_interpolation.rs`.
Keywords: rust, rustlang, rust-lang

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81

    use crate::{RealField, Rotation2, Rotation3, SimdRealField, UnitComplex, UnitQuaternion};

    /// # Interpolation
    impl<T: SimdRealField> Rotation2<T> {
        /// Spherical linear interpolation between two rotation matrices.
        ///
        /// # Examples:
        ///
        /// ```
        /// # #[macro_use] extern crate approx;
        /// # use nalgebra::geometry::Rotation2;
        ///
        /// let rot1 = Rotation2::new(std::f32::consts::FRAC_PI_4);
        /// let rot2 = Rotation2::new(-std::f32::consts::PI);
        ///
        /// let rot = rot1.slerp(&rot2, 1.0 / 3.0);
        ///
        /// assert_relative_eq!(rot.angle(), std::f32::consts::FRAC_PI_2);
        /// ```
        #[inline]
        #[must_use]
        pub fn slerp(&self, other: &Self, t: T) -> Self
        where
            T::Element: SimdRealField,
        {
            let c1 = UnitComplex::from(self.clone());
            let c2 = UnitComplex::from(other.clone());
            c1.slerp(&c2, t).into()
        }
    }

    impl<T: SimdRealField> Rotation3<T> {
        /// Spherical linear interpolation between two rotation matrices.
        ///
        /// Panics if the angle between both rotations is 180 degrees (in which case the interpolation
        /// is not well-defined). Use `.try_slerp` instead to avoid the panic.
        ///
        /// # Examples:
        ///
        /// ```
        /// # use nalgebra::geometry::Rotation3;
        ///
        /// let q1 = Rotation3::from_euler_angles(std::f32::consts::FRAC_PI_4, 0.0, 0.0);
        /// let q2 = Rotation3::from_euler_angles(-std::f32::consts::PI, 0.0, 0.0);
        ///
        /// let q = q1.slerp(&q2, 1.0 / 3.0);
        ///
        /// assert_eq!(q.euler_angles(), (std::f32::consts::FRAC_PI_2, 0.0, 0.0));
        /// ```
        #[inline]
        #[must_use]
        pub fn slerp(&self, other: &Self, t: T) -> Self
        where
            T: RealField,
        {
            let q1 = UnitQuaternion::from(self.clone());
            let q2 = UnitQuaternion::from(other.clone());
            q1.slerp(&q2, t).into()
        }

        /// Computes the spherical linear interpolation between two rotation matrices or returns `None`
        /// if both rotations are approximately 180 degrees apart (in which case the interpolation is
        /// not well-defined).
        ///
        /// # Arguments
        /// * `self`: the first rotation to interpolate from.
        /// * `other`: the second rotation to interpolate toward.
        /// * `t`: the interpolation parameter. Should be between 0 and 1.
        /// * `epsilon`: the value below which the sinus of the angle separating both rotations
        /// must be to return `None`.
        #[inline]
        #[must_use]
        pub fn try_slerp(&self, other: &Self, t: T, epsilon: T) -> Option<Self>
        where
            T: RealField,
        {
            let q1 = UnitQuaternion::from(self.clone());
            let q2 = UnitQuaternion::from(other.clone());
            q1.try_slerp(&q2, t, epsilon).map(|q| q.into())
        }
    }