I am using this webpage to build some of my methods for my game engine's quaternion class.
I am having trouble with the vector rotation via quaternion code. In the webpage cited above, this is what it looks like.
// Multiplying a quaternion q with a vector v applies the q-rotation to v Vector3 Quaternion::operator* (const Vector3 &vec) const { Vector3 vn(vec); vn.normalise();
So I use it in my quaternion class but I get incorrect results.
This is what I do to test the method...
Vector3 pos = new Vector3(1.0f, 0.0f ,0.0f);
Quaternion q = new Quaternion(0.0f, 0.0f, 45f);
pos = q.Rotate(pos);
To my current perspective, this will give me <~-0.707, ~0.707, 0.0f>. But it doesn't, I get <-0.13529904, 0.3535534, -0.3744762>, which seems to me to be way off.
Here is my code for the quaternion-vector rotation method...
/** * Multiplys a quaternion q with a vector v to apply the q-rotation to v */ public Vector3 Rotate (Vector3 vec) { vecnormal.Set(vec); vecnormal.Normalize(); qVec.x = vecnormal.X; qVec.y = vecnormal.Y; qVec.z = vecnormal.Z; qVec.w = 0.0f;
Use a debugger to see where things are going wrong. I built a quaternion using you code to convert Euler angles to a quaternion and then tested the same rotation of (1,0,0) using angles (0,0,45), but my results were correct: #include <iostream> #include <boost/math/quaternion.hpp> #include <cmath>
Heres my Quaternion.Multiply, just in case public Quaternion Multiply(Quaternion qLocal) { w = ((w * qLocal.w) - (x * qLocal.x) - (y * qLocal.y) - (z * qLocal.z)); x = ((w * qLocal.x) + (x * qLocal.w) + (y * qLocal.z) - (z * qLocal.y)); y = ((w * qLocal.y) + (y * qLocal.w) + (z * qLocal.x) - (x * qLocal.z)); z = ((w * qLocal.z) + (z * qLocal.w) + (x * qLocal.y) - (y * qLocal.x));
normalRegenerationCount++; return this; }
Oh, that's all messed up. You are using the same w,x,y,z variables for input and output, and as you do the computations you forget the old values, which you still need for the lines following. You are probably better off implementing a function that takes two quaternions and returns a fresh one, instead of having one of the quaternions be both source and destination.
Cool! Thats was indeed the issue! You saved me alot of time, thanks! I have another question regarding the result of quaternion - vector rotation. I noticed that If I were to pass <5.0, 0.0,0.0> I get a normal (0.707107,0.707107,0) as If I passed in <1.0, 0.0,0.0>.
Does quaternion rotation with vector only work with vector normals? Or might I have messed something else up in my class?
Generalist Game Developer and Cofounder at Voidseer Realms
To the method to rotate the vector by a quaternion.
/** * Multiplys a quaternion q with a vector v to apply the q-rotation to v */ public Vector3 Rotate (Vector3 vec) { vecnormal.Set(vec); vecnormal.Normalize(); qVec.x = vecnormal.X; qVec.y = vecnormal.Y; qVec.z = vecnormal.Z; qVec.w = 0.0f;
The result is always normal, no matter the magnitude of the input vector. Is this correct in the context of vector rotation via a quaternion? I was expecting the vector to be returned as a coordinate. I could ofcourse, could mutiply the result normal by the magnitude of the input vector. But I want to be sure if by definition, q * p * q-1 returns a rotated normal, or coordinate.
Generalist Game Developer and Cofounder at Voidseer Realms
True! Lol, Thanks for pointing that out, I should have noticed that normalization was not critical to the rotation calculation. Thanks for all your help!
Generalist Game Developer and Cofounder at Voidseer Realms