pub(crate) fn distance_3d(a: [f32; 3], b: [f32; 3]) -> f32 {
let dx = a[0] - b[0];
let dy = a[1] - b[1];
let dz = a[2] - b[2];
(dx * dx + dy * dy + dz * dz).sqrt()
}
pub(crate) fn distance_2d(a: [f32; 3], b: [f32; 3]) -> f32 {
let dx = a[0] - b[0];
let dy = a[1] - b[1];
(dx * dx + dy * dy).sqrt()
}
pub(crate) fn magnitude_3d(v: [f32; 3]) -> f32 {
(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]).sqrt()
}
pub(crate) fn normalize_quaternion(q: &mut [f32; 4]) {
let mag = (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]).sqrt();
if mag > 0.0 {
*q = [q[0] / mag, q[1] / mag, q[2] / mag, q[3] / mag];
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn distance_3d_measures_euclidean_distance_in_all_three_axes() {
assert_eq!(distance_3d([0.0, 0.0, 0.0], [3.0, 4.0, 0.0]), 5.0);
assert_eq!(distance_3d([1.0, 2.0, 3.0], [1.0, 2.0, 3.0]), 0.0);
assert_eq!(distance_3d([0.0, 0.0, 0.0], [0.0, 0.0, 5.0]), 5.0);
}
#[test]
fn distance_2d_ignores_the_z_component() {
assert_eq!(distance_2d([0.0, 0.0, 0.0], [3.0, 4.0, 100.0]), 5.0);
}
#[test]
fn magnitude_3d_computes_the_l2_norm() {
assert_eq!(magnitude_3d([3.0, 4.0, 0.0]), 5.0);
assert_eq!(magnitude_3d([0.0, 0.0, 0.0]), 0.0);
}
#[test]
fn normalize_quaternion_scales_to_unit_length() {
let mut q = [0.0, 0.0, 0.0, 2.0];
normalize_quaternion(&mut q);
assert_eq!(q, [0.0, 0.0, 0.0, 1.0]);
}
#[test]
fn normalize_quaternion_is_a_no_op_for_a_zero_quaternion() {
let mut q = [0.0, 0.0, 0.0, 0.0];
normalize_quaternion(&mut q);
assert_eq!(q, [0.0, 0.0, 0.0, 0.0]);
}
}