Extracting an object's forward vector from their rotation quaternion

Started by
9 comments, last by apatriarca 11 years, 10 months ago
So the way I am currently trying to achieve this is like so

public void GetForwardVector( Quaternion quatRot )
{
Quaternion quatInverse = GetQuaternionInverse( quatRot ); // Quaternion Conjugate / Quaternion Magnitude
Vector3 vecFwd = quatInverse * Vector3.Forward;

return vecFwd;
}

However this seems to give me a reflected forward vector. Multiplying by -Vector3.Forward doesn't seem to give me what I want either. Any ideas? Thanks!

xdpixel.com - Practical Computer Graphics

Advertisement
[s]Why inverse? Shouldn't you just multiply the quaternion by the global forward vector[/s]

Gotta read up on quaternions again...

EDIT:
The general method is to convert the quaternion to a rotation matrix. You can easily extract the 3 basis vectors from there.
There is a method to rotate a vector directly by a quaternion. To quote SiCrane from this thread. http://www.gamedev.net/topic/264455-direct-quaternion-vector-rotation/


p' = q * p * q[sup]-1[/sup]

where p is a pure quaternion made from the 3-vector to be rotated. A pure quaternion just takes the vector components as the i, j, and k terms with no scalar quantity or on other notations (0, v). So it becomes the normal multiplication of three quaternions.
[/quote]
I think you just have an inverse extra.

If you have a quaternion that represents the local->world orientation transform of the object, and you know the local-space forward direction of the object, you can get the world-space forward direction of the object by conjugating the vector by the quaternion. In terms of your code example, that would be


public void GetForwardVector( Quaternion quatRot )
{
return quatRot * Vector3.Forward;
}

I think you just have an inverse extra.

If you have a quaternion that represents the local->world orientation transform of the object, and you know the local-space forward direction of the object, you can get the world-space forward direction of the object by conjugating the vector by the quaternion. In terms of your code example, that would be


public void GetForwardVector( Quaternion quatRot )
{
return quatRot * Vector3.Forward;
}



No, the formula quoted about is correct (http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation) and is equivalent to Rodrigues formula.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Hmm, I'm probably missing something about the problem formulation, since I can't still see a flaw in my example. If I have an object with a local->world transform M (be it represented by a matrix or a quaternion), and I know that in that object's local space the vector v corresponds to the forward direction the model is facing towards, then I would apply M to v (in case of a matrix, either M*v or v*M depending on my convention, and in case of a quaternion, conjugate) to compute the direction vector in world space the model is facing towards.

Or perhaps the question was about something else, that I'm missing?
Your example is correct, IF you overload operator * to mean: p' = q * p * q[sup]-1[/sup] wink.png

Hmm, I'm probably missing something about the problem formulation, since I can't still see a flaw in my example. If I have an object with a local->world transform M (be it represented by a matrix or a quaternion), and I know that in that object's local space the vector v corresponds to the forward direction the model is facing towards, then I would apply M to v (in case of a matrix, either M*v or v*M depending on my convention, and in case of a quaternion, conjugate) to compute the direction vector in world space the model is facing towards.

Or perhaps the question was about something else, that I'm missing?


Well, multiplication by a quaternion is not equivalent to multiplication by a matrix even though they may represent the same rotation. If we have a quaternion,

q = (w,x,y,z)

where w is the real part, and we want it to represent a rotation, theta, about a unit vector u = (ux, uy, uz) then we define

w = cos(theta)
x = ux * sin(theta)
y = uy * sin(theta)
z = uz * sin(theta)

Multiplying a vector (written as a quaternion) with the elements (a,b,c), the equivalent matrix multiplication is,

[w -x -y -z][0]
[x w -z y][a]
[y z w -x]
[z -y x w][c]

Now the (almost) anti-symmetric structure of the matrix can result in an actual rotation matrix (I believe this is the case when the rotation axis coincides with the axes of the co-ordinate system). However, this is not the rotation matrix you should get for the equivalent axis-angle representation, which is given by

[ 0 -uz uy]
S = [ uz 0 -ux]
[-uy ux 0]

R = I + sin(theta) * S + (1 - cos(theta)) * S^2

where I is the identity matrix, and the (ux,uy,uz) and theta are the same as those used above. The most obvious difference is the squared term at the end of the expression for the rotation matrix. This is something that is absent when the vector is multiplied by the quaternion. I would guess that the effect of the post-multication by the inverse of the quaternion introduces the quadratic effect provided by S^2.


-Josh

Edit: apologies for the awful formatting.

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Ah. In my both examples, I meant multiplication by quaternion to mean conjugation, and wrote in conjugation in the text to convey that, since that's a common practice in math libraries and game engines (e.g. Ogre).

Ah. In my both examples, I meant multiplication by quaternion to mean conjugation, and wrote in conjugation in the text to convey that, since that's a common practice in math libraries and game engines (e.g. Ogre).


Right, the conjugate of a quaternion is equivalent to its inverse when it has unit length.

-Josh

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet


[quote name='clb' timestamp='1339738730' post='4949443']
Ah. In my both examples, I meant multiplication by quaternion to mean conjugation, and wrote in conjugation in the text to convey that, since that's a common practice in math libraries and game engines (e.g. Ogre).


Right, the conjugate of a quaternion is equivalent to its inverse when it has unit length.

-Josh
[/quote]

That's not what I was referring to. What I am saying is that in the code


public void GetForwardVector( Quaternion quatRot )
{
return quatRot * Vector3.Forward;
}


it is the custom to have the operator * denote conjugation q * v * q^-1 already, see e.g. Ogre, Irrlicht (line 626) or libcinder. This is not related to the property you mentioned.

This topic is closed to new replies.

Advertisement