rotate_a_to_b_shortest

Function rotate_a_to_b_shortest 

Source
pub fn rotate_a_to_b_shortest<T>(
    a: Vector3<T>,
    b: Vector3<T>,
) -> Option<Quaternion<T>>
where T: Float,
Expand description

Calculate the versor to rotate from vector a to vector b by the shortest path.

This function calculates q satisfying b = point_rotation(q, a) when norm(a) = norm(b).

§Characteristics

  • Shortest Path: This method guarantees the rotation axis is always orthogonal to both vector a and vector b, representing the geometrically shortest path between the two directions.
  • Rotation Angle: The rotation angle is in the range [0, PI] radians.
  • Parallel Vectors: If vector a and b are opposite and parallel, the rotation axis is theoretically ambiguous. This function provides a valid rotation, but the axis direction is not guaranteed (although it will be orthogonal to the a and b).

§Performance Consideration

This function is slightly more computationally intensive than rotate_a_to_b, especially when the angle between the vectors is near PI. If an orthogonal rotation axis is not strictly required, rotate_a_to_b may be preferred for performance.

§Returns

Returns None if either input vector a or b is a zero vector, as a rotation cannot be uniquely defined in that case.

§Examples

let a: Vector3<f64> = [1.5, -0.5, 0.2];
let b: Vector3<f64> = [0.1, 0.6, 1.0];
 
let q = rotate_a_to_b_shortest(a, b).unwrap();
let b_check = point_rotation(q, a);
 
let b_u = normalize(b);
let b_check_u = normalize(b_check);
assert!( (b_u[0] - b_check_u[0]).abs() < 1e-12 );
assert!( (b_u[1] - b_check_u[1]).abs() < 1e-12 );
assert!( (b_u[2] - b_check_u[2]).abs() < 1e-12 );
 
// --- If the amount of displacement of vector `a` is to be adjusted --- //
// The parameter `t` adjusts the amount of movement from `a` to `b`. 
// When `t = 1`, `a` moves completely to position `b`.
let t = 0.5;
let mut q = rotate_a_to_b_shortest(a, b).unwrap();
let r = to_rotation_vector(q);  // To avoid singularities, proceed via the rotation vector.
q = from_rotation_vector(scale(t, r));