• Advertisement
Sign in to follow this  

Multiply a vector3 by a quaternion

This topic is 2650 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I would like to multiply a vector3 (like a normalized look vector) by a rotation represented by a quaternion. I am using DirectX 9's math library and I noticed they don't define vector4 * vector3 multiplication.

I have some pseudocode like this:

Vector3 lookDir, lookDirGoal;
Quaternion q;

lookDirGoal = (q * lookDir);

Would this produce the desired result (lookDirGoal = q * lookDir)?


D3DXQUATERNION q = D3DXQUATERNION (0, 0, 0, 1 );
D3DXVECTOR3 lookDir, lookDirGoal;

//
// Assume 'q' is filled in with some desired rotation.
//

q *= D3DXQUATERNION( lookDir.x, lookDir.y, lookDir.z, 1.0f );
lookDirGoal = D3DXVECTOR3( q.x, q.y, q.z );
D3DXVec3Normalize( &lookDirGoal, &lookDirGoal );



Basically I am promoting the vector3 to a vector4 with the fourth component of 1.0f (should it be 0.0f instead?) and then doing quaternion by quaternion multiply (which is defined)...and then truncating the quaternion back to a vector3 and normalizing it to get the direction?

Share this post


Link to post
Share on other sites
Advertisement
You need to brush up on your quaternion math. Generally, rotating a vector using
a quaternion is:

v' = v q v* (where v* is the conjugate quaternion, normally its trivial to compute).

Many game programming books (engines, collision detection, graphics) talk about
quaternions but you can even read on this in wikipedia, just look up "quaternion rotation" in google...

Share this post


Link to post
Share on other sites
Thanks for the reply, is 'v' the vector and 'q' the quaternion in your formula above.

v' = v q v*

It is easy to conjugate a quaternion (just negate all its components except 'w') but I still don't see how to multiply the vector3 by the vector4.

Basically your answer doesn't make sense to me. (q * v*) is just the original quaternion multiplied by its conjugate, which seems odd. And even after that how do you multiply 4 numbers by 3?

(v'[x], v'[y], v'[z]) = (v[x], v[y], v[z]) * (q[x], q[y], q[z], q[w]) * (-q[x], -q[y], -q[z], q[w])

Share this post


Link to post
Share on other sites
Quote:
Original post by Steve_Segreto
Thanks for the reply, is 'v' the vector and 'q' the quaternion in your formula above.
Actually, it looks like voguemaster may have mistyped. It should be:
v' = q v q*
As for the multiplication, for the purposes of this operation, the vector v is encoded as a quaternion by assigning the x, y, and z elements of the vector to the corresponding elements of the quaternion, and assigning an arbitrary value (typically zero) to the quaternion's w element. The quaternion multiplication is then carried out, and the result is extracted from the resulting quaternion (the w element can be ignored).

Share this post


Link to post
Share on other sites
Thanks! So this should be the correct way to rotate a vector using a quaternion?

Let rq and q be quaternions and v' be the vector v rotated by q.

(rq[x], rq[y], rq[z], rq[w]) = (q[x], q[y], q[z], q[w]) * (v[x], v[y], v[z], 1.0f) * (-q[x], -q[y], -q[z], q[w])

(v'[x], v'[y], v'[z]) = (rq[x], rq[y], rq[z])


//
// Rotate the vector pV by the rotation described in pQ.
// Return the rotated vector.
//
D3DXVECTOR3 D3DXVec3Rotate( const D3DXVECTOR3 *pV, const D3DXQUATERNION *pQ )
{
D3DXQUATERNION q1, q2;
D3DXQuaternionConjugate( &q1, &q1 );
q2 = *pQ * D3DXQUATERNION( pV->x, pV->y, pV->z, 1.0f ) * q1;

return D3DXVECTOR3( q2.x, q2.y, q2.z );
}

Share this post


Link to post
Share on other sites
It looks like you have the right idea, but I think there might be an error or two in your example code.

Also, you might double check the multiplication order for quaternions in the DirectX math library. IIRC, DX uses 'reverse' quaternion multiplication order for consistency with the library's use of row-vector notation. If that is the case, you'll probably want q*vq rather than qvq*. (The only difference between the two being that they'll rotate the input vector in opposite direction.)

Share this post


Link to post
Share on other sites
Hi,

Ack, I did mistype. I blame tiredness and the late hour... heh sorry.
BTW, What jyk said about the ordering of the elements in matrices and vectors
is crucial. You always must pay attention who expects what kind of ordering:
row-major or column-major.

Eli

Share this post


Link to post
Share on other sites
Quote:
Original post by Steve_Segreto
@jyk: By errors do you mean the example function would not rotate the vector by the quaternion as desired?
The basic idea is right, but I think this line:
D3DXQuaternionConjugate( &q1, &q1 );
Might be wrong (q1 hasn't had anything assigned to it yet).

Share this post


Link to post
Share on other sites

D3DXVECTOR3 *D3DXVec3Rotate( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV, const D3DXQUATERNION *pQ )
{
D3DXQUATERNION q1, q2;
D3DXQuaternionConjugate( &q1, pQ );
q2 = q1 * D3DXQUATERNION( pV->x, pV->y, pV->z, 1.0f ) * *pQ;

*pOut = D3DXVECTOR3( q2.x, q2.y, q2.z );
return pOut;
}




Looks like I was conjugating the wrong thing in my last post ;)

EDIT: Ninja'd and I still got it wrong twice...grrr

[Edited by - Steve_Segreto on October 19, 2010 9:50:10 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement