Sign in to follow this  
Melanikus

Quaternion problems

Recommended Posts

Hey there, it's my 1st post, so sorry for any noobness I'm having some trouble with quaternions, I'm sorry if I can't provide much detail but I believe that anyone who messed with D3DXQUATERNIONS had them, they seem to be a bit unstable sometimes. I was making this roll/pitch/yaw functions by getting the local axis for my object (by converting my quaternion to a rotation matrix thru D3DXMatrixRotationQuaternion) and rotating around them. Well after a certain angle my object starts to spin in every direction O_o By googling a little I found out that giving 2 "directions" A and B there are two quaternions that can perform it, a quaternion and it's "inverse" but when point A and B are exactly opposite (180degrees) there's an infinite number of quaternions that can perform the rotation, that's the reason it "screws up". Well, to solve that, I tried to leap to the next valid position, so, if my quaternion was > 90 it should go to -90, strangely instead of jumping it seems that it did a 360 degree spin to the other way and then started rotating in the right direction again... I simply DID NOT coded that... it goes to "0", then it goes to something close to 10 degrees, go back to about 2 degrees, then to -89 or something... and starts rotating normally... I know it sounds kinda crazy... but It's happening, any clues? I could send the exe if someone's interested Here's a little demonstration of the values of the W on the quaternion and the values in degrees (later converted to radians) in the moment this kind of thing happens http://img40.imageshack.us/img40/1874/quatweird.jpg

Share this post


Link to post
Share on other sites
Quote:
I'm having some trouble with quaternions, I'm sorry if I can't provide much detail but I believe that anyone who messed with D3DXQUATERNIONS had them, they seem to be a bit unstable sometimes. I was making this roll/pitch/yaw functions by getting the local axis for my object (by converting my quaternion to a rotation matrix thru D3DXMatrixRotationQuaternion) and rotating around them. Well after a certain angle my object starts to spin in every direction O_o
There are no stability problems with D3DXQUATERNION (or with quaternions in general) aside from baseline issues with numerical precision, so if you're not getting the behavior you expect, it's probably just due to an error in your implementation.
Quote:
By googling a little I found out that giving 2 "directions" A and B there are two quaternions that can perform it, a quaternion and it's "inverse" but when point A and B are exactly opposite (180degrees) there's an infinite number of quaternions that can perform the rotation, that's the reason it "screws up".
If you're talking about finding a quaternion that will rotate a vector A on to a vector B, there's actually an infinite number that will do this, but (in general) only two that will perform the rotation over the shortest arc. Also, these two quaternions are negatives of each other, not inverses.

As you note, when the vectors are oppositely aligned, there isn't a unique solution to the 'shortest arc' problem.

I'm not quite clear on what you're trying to do, so I probably can't help much more than that (at least not without some more information).

Share this post


Link to post
Share on other sites
Assuming that _absoluteRotation is a D3DXQUATERNION in my class representing the rotation =~/

void myclass::yaw(float angle)
{
D3DXMATRIX localSpace;
D3DXQuaternionNormalize(&_absoluteRotation,&_absoluteRotation);
D3DXMatrixRotationQuaternion(&localSpace,&_absoluteRotation); // get local XYZ axis
D3DXVECTOR3 yAxis = D3DXVECTOR3(localSpace._21,localSpace._22,localSpace._23); // Get Y axis
D3DXVec3Normalize(&yAxis,&yAxis);
D3DXQUATERNION rotation;
D3DXQuaternionRotationAxis(&rotation,&yAxis,angle); // Rotate around Y quat
D3DXQuaternionNormalize(&rotation,&rotation);
D3DXQuaternionMultiply(&_absoluteRotation,&_absoluteRotation,&rotation); // multiply by current orientation
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Melanikus
Well, to solve that, I tried to leap to the next valid position, so, if my quaternion was > 90 it should go to -90, strangely instead of jumping it seems that it did a 360 degree spin to the other way and then started rotating in the right direction again...


mmmm... WHAT?
Seriously, I don't get what you were trying to do (which seems you wanted to perform a 180° rotation), how you tried to fix it, and what result you're getting.

Could you rephrase and explain it all again please?

Cheers
Dark Sylinc

Share this post


Link to post
Share on other sites
Yeah I know, sorry guys...
The thing is even I didn't understand the problem correctly, I was using some functions incorrectly which led to this weird problems, it's all working now, I would love to know the math behind what I was doing wrong, but I'll leave as it... quaternions have no stability problems, I was screwing up =p

Thanks anyway, posting here made me double check some stuff, it's all working now

Share this post


Link to post
Share on other sites
Ok this isn't working... [depressed] [depressed] [depressed]
I'm trying to make a VERY SIMPLE roll/pitch/yaw around the local axis... and it's not working, here's the code...

void MyObject::pitch(float angle)
{
// Get rotationg matrix returns MyObject's Quaternion->Matrix conversion
D3DXMATRIX localSpace = getRotationMatrix();
// I take the x axis from it (elements m11,m12,m13)
D3DXVECTOR3 xVector = D3DXVECTOR3(localSpace._11,localSpace._12,localSpace._13);

// And then I "Rotate the quaternion" around xVector/angle (in radians)
D3DXQuaternionRotationAxis(&_rotation,&xVector,angle);
}


For yaw/roll I just change the axis (x,z) and the matrix positions

So this is a very simple code, my code has asserts/checks for normalized vecs/quaternions, out of PI range (for radians) so on, it's all fine, and this code also works fine, but If I do something like

MyObject * obj = new MyObject;
obj->pitch(angle);
obj->yaw(angle);

It rotates correctly for a moment then it starts to go berserk, there's no way of explaining, so I've made an youtube video, hope you guys can help =/

Quaternion problem youtube video

I also tried creating the rotation quaternion for let's say pitch and yaw and then multiplying (Quaternion multiply should be == concatenating rotations) but that did not work either (same effect actually) that's not the only piece of code that that happens, I've tried several other stuff (in many ways) and nothing worked, I'm about to give up quaternions for matrices =/

Thanks

Share this post


Link to post
Share on other sites
Ok one more thing, I'm not getting how do you "concatenate" quaternions, shouldn't quaternion multiply do this? cause, right now I tried to use


D3DXQuaternionRotationYawPitchRoll(quat,angle1,angle2,angle3)





and it worked

But when I tried

D3DXQuaternionRotationYawPitchRoll(&myRotation,angle1,0,0)
D3DXQuaternionRotationYawPitchRoll(&myRotation,0,angle2,0)





I only got the rotation around the Y axis, so "D3DXQuaternionRotationYawPitchRoll" creates a quaternion that has those values for yaw/pitch/roll, unlike D3DXQuaternionAxisAngle which ROTATES A QUATERNION around an axis/angle (instead of creating one that represents the rotation of the axis/angle) ok... then I tried


D3DXQUATERNION result;
D3DXQuaternionRotationYawPitchRoll(&result,angle1,0,0)
myRotation *= result;

D3DXQuaternionRotationYawPitchRoll(&result,0,angle2,0)
myRotation *= result;





Shouldn't this be the same as D3DXQuaternionRotationYawPitchRoll(&myRotation,angle1,angle2,0) ??? because it's not... I get the same problem I got in the youtube video I showed...

Edit: Solved the problem, thnx to the ppl who replied anyway

[Edited by - Melanikus on August 19, 2009 1:46:06 PM]

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