fu5ha/ultraviolet

Conversions between a Rotor3 and quaternions

expenses opened this issue · 3 comments

Ultraviolet is awesome and I love using rotors, but it's tricky to integrate it with other geometry crates such as ncollide3d because you have to convert Rotor3s by going though Rotor3 -> Mat3 -> array -> other matrix type -> quaternion type. It would be lovely to have two conversion functions like:

fn from_quaternion_array(quaterion: [f32; 4]) -> Self;
fn to_quaternion_array(&self) -> [f32; 4];

I'm happy to implement this, but I've been unable to find out the maths to do this thus far.

According to paragraph 3.8 of this article writing those functions should be quite easy: one just need to swap the first and third component of the imaginary part. For example r.to_quaternion_array() = [q.s, q.bv.yz, q.bv.xz, q.bv.xy]

@thenlevy awesome, thanks! From experimenting, I'm pretty sure you have to invert the i and j (here x and z) parts of the quaternion, but I haven't worked out why:

fn na_quaterion_to_rotor(quaternion: ncollide3d::na::geometry::Quaternion<f32>) -> Rotor3 {
    Rotor3::new(quaternion.coords.w, ultraviolet::Bivec3::new(-quaternion.coords.z, quaternion.coords.y, -quaternion.coords.x))
}
fu5ha commented

The i/j (x/z) components need to be inverted because ultraviolet currently uses the xz basis vector rather than the zx basis vector (i.e. pointed the opposite direction), which is common in other literature/implementations.