Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

quaternion vector product

Started by doogyhatts Oct 2, 2007 at 3:48 AM 10 replies 4.2k views
Original Post
doogyhatts
doogyhatts
Hi, I looked at OGRE before and they had a portion of the quaternion code taken from NVidia SDK. I am trying to understand the math for the product of a quaternion with a vector.

template<typename T>
Vector3D<T> Quaternion<T>::operator * (Vector3D<T> V)
{
	Vector3D<T> uv, uuv;
	uv = Axis.Cross(V);
	uuv = Axis.Cross(uv);
	uv *= (2.0f * Angle);
	uuv *= 2.0f;
	return V + uv + uuv;
}

Can someone enlighten me on this matter? thx! Edwin
Neon2302
Neon2302
Not quite sure, but my idea is

Vector3D uv, uuv;
instantiate vector uv and uuv

uv = Axis.Cross(V);
cross vector Axis and V and keep it in uv
Axis should be the Axis of quaternion (so the quaternion is keep in form of angle and axis of the rotation instead of float[4])

uuv = Axis.Cross(uv);
same as last sentence

uv *= (2.0f * Angle);
multiply angle by 2 and multiply them to uv (don't know the Angle is degree or radian)

uuv *= 2.0f;
multiply vector uuv by 2 (multiply each element by 2)

return V + uv + uuv;
return the sum of 3 vector (add V[0] with uv[0] with uuv[0], V[1] with uv[] ...)
doogyhatts
doogyhatts
Actually the code snippet above was my own, rather i used a reference from the source code OGRE had in, and tailor the syntax to my own math lib.

I am actually asking for explanation on a mathematical point of view, eg why do u do the cross product and then multiply by 2 and then the angle? This portion is related to the quaternion and axis-angle relational proof. However, this is all I could understand for now.

I am still trying to figure out the rest. 5 stars for anyone who can help...

thx!
Edwin
Vern777
Vern777
I'm still looking into this, but in Mathematics for 3D game programming and Computer graphics, there is a derivation:

qPq^-1 = (s^2-v^2)P+2sv x P +2(.P)v

Where v, and P are vectors. Note this looks surprisingly like what we have...

I'll try to work this out, be back.
Vern777
Vern777
Hey I looked at the Ogre source (hehe I have it on my harddrive)...

It's a bit different from your code since they multiplies by w instead of angle.

Anyway, if you expand qPq^-1, where we define q = s + v, that is, s is scalar v a vector. One can see that we get something similar, that is:

qPq^-1 = s^2P + 2s v x P +v(v.p)v - v^2P + v x p x v       = (s^2-v^2)p + 2 s v x P + 2(v.p)v


This follows from the identity v x p x v.

That's very close to what we have. So now I'm trying to work out what v x v x p.

Also the code kind hints at this, since they named the variable uv, and uuv, does it mean u x v and u x u x v? It sure looks like it.

I still trying to work out the details.

Vern777
Vern777
I got it!!!

From the code, we have:

return v + 2*s*uv + 2*uuv.I'm gonna write this as,P + 2s v x P + vx(vxP) (1)Now v = tA, where A is a unit vector.So (using the identity v x (v x p) here)P + 2s v x P + 2 [v x (v x P)] = P + 2stA x P + 2 [ tA(tA.P) - t^2A^2P] ].But A^2 is 1.So this lead us to,P + 2s tA x P + 2 [ tA(tA.P) - t^2A^2P] = (1-2t^2)P + 2s tA x P + 2 tA(tA.P)                                         = (s^2 - t^2)P + 2s tA x P + 2 tA(tA.P) (2)Notice that, 1 = s^2 + t^2.We can derive (2) from qPq^-1, where q = s + v!
doogyhatts
doogyhatts
thx to all who replied!

Actually I went to do some testing and found that if you use the standard derivation for rotating a vector by a quaternion, the result is similar to the one given by OGRE's code (or more correctly, by NVidia rather).

In short, it looks like an optimised version compared to the standard derivation.

thx again!
Edwin
Vern777
Vern777
Yeah, it definitely looks like optimize code.

I would never have thought about doing it that way...

BTW, I did a write up on my blog:

http://9yinjing.blogspot.com/2007/10/some-really-nerdy-quaternion-stuff.html

It has some latex equations so it's a bit more clear than here...




Vorpy
Vorpy
Calling the components of a quaternion "Axis" and "Angle" is a bit misleading. For the purpose of rotating vectors, the imaginary part does point in the direction of the axis of rotation, but the magnitude of the real part and the imaginary part are cos(angle/2) and sin(angle/2). Of course this inclusion of trigonometric ratios explains how rotating with quaternions can be so much nicer than rotating by an axis-angle representation.
Vern777
Vern777
Yeah of course.

But, in the code above, it is defining a * operation between a quaternion and a vector. The only sensible operation here is qPq^-1 (I think), with P a pure quaternion, representing the vector V, in the code above. Remember he took this code from Ogre3D's code, which is based on the implementation in the Nvidia SDK. Everything is sort implied...

It is implied that the quaternion is q = s + v = cos(t/2) + sin(t/2)A.

With A a unit vector, our axis of rotation.

This implies that q = s + tA.

From this we get the optimized code above.


Vern777
Vern777
Right, he is calling it Axis, and Angle. Which is not necessary true.

It should just be let q = w + xi + yj + zk,

then,

Vector3 quaternion::operator * (Vector3 v)

uv = [x,y,z].crossProduct(v)
uuv = [x,y,z].crossProduct(uv)

uv *= 2*w;
uuv *= 2;

return v + uv + uuv.

Yeah, calling [x,y,z], w, Axis and Angle is not necessarily true.

Vern777
Vern777
DUPLICATED POST, SORRY!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.