What's the uniqueness of the result of `UnitQuaternion::rotation_between`?

I found the following function rustdoc in the latest nalgebra library:


    /// The unit quaternion needed to make `a` and `b` be collinear and point toward the same
    /// direction. Returns `None` if both `a` and `b` are collinear and point to opposite directions, as then the
    /// rotation desired is not unique.
    ///
    /// # Example
    /// ```
    /// # #[macro_use] extern crate approx;
    /// # use nalgebra::{Vector3, UnitQuaternion};
    /// let a = Vector3::new(1.0, 2.0, 3.0);
    /// let b = Vector3::new(3.0, 1.0, 2.0);
    /// let q = UnitQuaternion::rotation_between(&a, &b).unwrap();
    /// assert_relative_eq!(q * a, b);
    /// assert_relative_eq!(q.inverse() * b, a);
    /// ```

mathematically, this rotation is underdefined (many unit quaternions could "make a and b be collinear and point toward the same direction"), so what makes this function significant? Is it the longest rotation, the shortest, or the one that avoided some axis (e.g. lat/lng rotation)?

If so, why is it not stated in the rustdoc like its scaled counterpart (copied as follow)?

    /// The smallest rotation needed to make `a` and `b` collinear and point toward the same
    /// direction, raised to the power `s`.
    ///
    /// # Example
    /// ```
    /// # #[macro_use] extern crate approx;
    /// # use nalgebra::{Vector3, UnitQuaternion};
    /// let a = Vector3::new(1.0, 2.0, 3.0);
    /// let b = Vector3::new(3.0, 1.0, 2.0);
    /// let q2 = UnitQuaternion::scaled_rotation_between(&a, &b, 0.2).unwrap();
    /// let q5 = UnitQuaternion::scaled_rotation_between(&a, &b, 0.5).unwrap();
    /// assert_relative_eq!(q2 * q2 * q2 * q2 * q2 * a, b, epsilon = 1.0e-6);
    /// assert_relative_eq!(q5 * q5 * a, b, epsilon = 1.0e-6);
    /// ```
1 Like

Yes it's probably the shortest rotation.

I also find the design where it returns an Option, with None for opposite vectors, to be a bad design. The checking whether the vectors are opposite is done approximately anyway, so that's not a reliable check. It might as well return an arbitrary 180 degree rotation in that case, that would be a lot more useful in any application I can think of than dealing with the None special case.

1 Like

"probably"? what's the probability tho :smiley:

for scaled_rotation_between it is 100% (according to the doc)

If you want a documented guarantee, an issue or PR on their repo is presumably the best way to (try to) get it.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.