Quaternion n00b

Started by
4 comments, last by Glass_Knife 10 years, 11 months ago

I have seen chapters and sections about quaternion rotation in countless programming books, but I have never needed to use them. With all the examples available I always assumed that they were easy. Oops. I've been reading about them and thinking about them, but the purpose still eludes me.

I have an OpenGL sphere representing a planet, and I thought that by using quaternion rotation I could avoid Gimbal lock. However, even with all the equations, I do not understand the code that I need to write. If I understand the math, a quaternion is represented as a vector and a scalar. q = [qv, qw] where qv is the vector (qx, qy, qz) and qw is the scalar. I understand that the regular vector is multiplied by sin(angle/2) and the scalar by cos(angle/2) to convert the regular vector into a quaternion vector and scalar.

I understand that quaternion multiplication uses the Grassman product with a dot product and a cross product. I also understand that the conjugate q* = [-qv, qw], and if the quaternion is normalized with a length of one, then the inverse and the conjugate are identical.

q^-1 = q*. The inverse is used to perform rotation of a vector. v' = qvq^-1. Multiply the quaternion by the vector, and then by the inverse. If I have made any mistakes so far please let me know.


Here is what I do not understand:

* To rotate a vector, does that vector need to be normalized? It also seems that I do not convert the vector to be rotated into a quaternion. It is just (vx, vy, vz, 0). But then after multiplication with the quaternion and inverse, I convert the result from the quaternion back to a vector?


* I have examples of turning a quaternion into a matrix, but when is this necessary? Do I convert the rotation into a matrix and multiply that by my current matrix? What happens to vectors multiplied by this matrix? Do they come on quaternions? It is very confusing.

* If I want to rotate my planet based on the user clicking and dragging the mouse, I don't understand what the code should do. What vector becomes the quaternion? What vector is rotated by the quaternion? How do I take the result and rotate the planet?

Hopefully I haven't been too confusing.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Advertisement

* To rotate a vector, does that vector need to be normalized? It also seems that I do not convert the vector to be rotated into a quaternion. It is just (vx, vy, vz, 0). But then after multiplication with the quaternion and inverse, I convert the result from the quaternion back to a vector?

To rotate a vector you have to convert it to an imaginary quaternion, i.e. a quaternion with the scalar part equal to zero and vector part equal to the vector you want to rotate. After the rotation you have to convert the quaternion back to a vector. But this is more conceptual than practical. You usually directly implement the logic of the rotation on vectors.

* I have examples of turning a quaternion into a matrix, but when is this necessary? Do I convert the rotation into a matrix and multiply that by my current matrix? What happens to vectors multiplied by this matrix? Do they come on quaternions? It is very confusing.

Quaternions are a more compact representation of rotation and they are more convenient for interpolation. However, they are usually converted to matrices to compose the rotation with other transformations (like translation or scaling). Vectors multiplied by this matrix are transformed as usual. There is no difference between this matrix and another rotation matrix computed in a different way.

* If I want to rotate my planet based on the user clicking and dragging the mouse, I don't understand what the code should do. What vector becomes the quaternion? What vector is rotated by the quaternion? How do I take the result and rotate the planet?

You usually define two points on the planet and then compute the quaternion which transform the initial point in the final point. The axis is usually computed using a cross product of the two vectors from the center of the planet through the two points and the angle is simply the angle between the two vectors.

You usually directly implement the logic of the rotation on vectors.


I am not sure what you mean by this. Do you mean just hard-code the math for each vector element?

You usually define two points on the planet and then compute the quaternion which transform the initial point in the final point. The axis is usually computed using a cross product of the two vectors from the center of the planet through the two points and the angle is simply the angle between the two vectors.

This sounds like the Matrix conversion converts to a regular version that is not in imaginary space, and so the vectors multiplied by this matrix do not need converted?

here is no difference between this matrix and another rotation matrix computed in a different way.


Do I then convert the vector to a yaw,pitch,roll and apply that rotation to the sphere?

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Rotating a vector by a quaternion by constructing a purely imaginary quaternion (0, v) (i.e. w = 0, xyz = vector part) from the vector and applying the rotation formula

v' = qvq*

always gives a purely imaginary quaternion back (i.e. a vector (0, v')) so there is no need to "convert" from a vector rotated by a quaternion back to a vector (it's basically an embedding of vectors in the quaternions).

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

The conversion is more theoretical than practical because an imaginary quaternion is really just a 3D vector. It is something in the form xi + yj + zk. Moreover, it is possible to use the properties of imaginary and unit quaternions to optimize the rotation formula to make it more efficient. In your code you may thus simply have a something like q.rotate(v) where q is quaternion and v is a 3D vector.

Quaternions, euler angles, matrices, axis-angle.. are different objects used to represent the same thing: a linear map from a 3D vector space to himself preserving distances and orientations*. The representation may change the way you see and interpret a single rotation, but the rotation itself is just a map from a vector to another. When you transform a quaternion to a matrix, the map remains the same, but you can now combine this transformation with translations, reflections, scalings..

* Note that I have written a linear map and not an affine map. Otherwise the set would also contains translations.

Thanks for the help understanding it all. I finally dug in and wrote some OpenGL code to do the rotation, and after coding all the math by hand and working through all the coding errors, I got it all working.

The 4th term, w, was what was throwing me off. If the rotation vector is normalized, then the quaternion is normalized too. The other thing that tripped me up was the "conversion" of the vector to be rotated. It is just the vector with a zero w term, and nothing needs to be done to it after it is converted.

I did fail when doing the conversion...

Converting from a vector v and a rotation r to a quaternion:

qx = v.x * sin(r/2);
qy = v.y * sin(r/2);
qz = v.z * sin(r/2);
qw = v.w * cos(r/2); <<< Error!!!

It should just be:
qw = cos(r/2);

So I lost a couple of hours second guessing myself. All in all, time well spent!

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

This topic is closed to new replies.

Advertisement