Sign in to follow this  
akaitora

Extracting an object's forward vector from their rotation quaternion

Recommended Posts

akaitora    399
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!

Share this post


Link to post
Share on other sites
Madhed    4095
[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 [b]SiCrane[/b] from this thread. [url="http://www.gamedev.net/topic/264455-direct-quaternion-vector-rotation/"]http://www.gamedev.net/topic/264455-direct-quaternion-vector-rotation/[/url]

[quote]
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] Edited by Madhed

Share this post


Link to post
Share on other sites
clb    2147
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

[code]
public void GetForwardVector( Quaternion quatRot )
{
return quatRot * Vector3.Forward;
}
[/code]

Share this post


Link to post
Share on other sites
jjd    2140
[quote name='clb' timestamp='1339702240' post='4949253']
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

[code]
public void GetForwardVector( Quaternion quatRot )
{
return quatRot * Vector3.Forward;
}
[/code]
[/quote]

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

-Josh

Share this post


Link to post
Share on other sites
clb    2147
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?

Share this post


Link to post
Share on other sites
Madhed    4095
Your example is correct, IF you overload operator * to mean: p' = q * p * q[sup]-1[/sup] [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img]

Share this post


Link to post
Share on other sites
jjd    2140
[quote name='clb' timestamp='1339711365' post='4949320']
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?
[/quote]

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][b]
[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. Edited by jjd

Share this post


Link to post
Share on other sites
clb    2147
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).

Share this post


Link to post
Share on other sites
jjd    2140
[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).
[/quote]

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

-Josh

Share this post


Link to post
Share on other sites
clb    2147
[quote name='jjd' timestamp='1339760747' post='4949504']
[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).
[/quote]

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

[code]
public void GetForwardVector( Quaternion quatRot )
{
return quatRot * Vector3.Forward;
}
[/code]

it is the custom to have the operator * denote conjugation q * v * q^-1 already, see e.g. [url="https://bitbucket.org/sinbad/ogre/src/3a7079ea6c89/OgreMain/src/OgreQuaternion.cpp#cl-399"]Ogre[/url], [url="http://irrlicht.svn.sourceforge.net/viewvc/irrlicht/trunk/include/quaternion.h?revision=4192&view=markup"]Irrlicht (line 626)[/url] or [url="https://github.com/cinder/Cinder/blob/master/include/cinder/Quaternion.h#L672"]libcinder[/url]. This is not related to the property you mentioned.

Share this post


Link to post
Share on other sites
apatriarca    2365
The fact that people are doing it does not mean it is the right thing to do. This is not correct matematically since the formula for rotation using quaternions is different and you are now using two very different multiplications on quaternions: one with quaternions and the other with vector. The main consequence of this is that it reduces the readability of your code and more mathematically inclined people will often repeat your code is wrong because it does not follows the usual equations. It also makes it harder to implement new code involving quaternions because the maths is different from your code. If you really want to overload something then it is better to overload the function application. After all, this is an action:
[code]
public void GetForwardVector( Quaternion quatRot )
{
return quatRot( vector3.Forward );
}
[/code]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this