Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

jesterlecodeur

Quaternion multiply problem

This topic is 6055 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

I use this to multiply quaternions:
  
INLINE CQuaternion& MultiplyQuaternion( CQuaternion& qOut, const CQuaternion &qA, const CQuaternion &qB )
{
	qOut.w = qA.w*qB.w - qA.x*qB.x - qA.y*qB.y - qA.z*qB.z;
	qOut.x = qA.w*qB.x + qA.x*qB.w + qA.y*qB.z - qA.z*qB.y;
	qOut.y = qA.w*qB.y - qA.x*qB.z + qA.y*qB.w + qA.z*qB.x;
	qOut.z = qA.w*qB.z + qA.x*qB.y - qA.y*qB.x + qA.z*qB.w;

	return qOut;
}
  
And this routine to convert quaternions to euler angles:
  
INLINE CVector3& CQuaternion::GetEulerAngles( CVector3& vc )
{
  float ww = w*w;
  float xx = x*x;
  float yy = y*y;
  float zz = z*z;

  vc.z = atan2f( 2.0f * (x*y + z*w),(xx - yy - zz + ww));
  vc.x = atan2f( 2.0f * (y*z + x*w),(-xx - yy + zz + ww));

  // The end is very thrash (the base end routine give the y angles only within [-PI/2, PI/2] )

  float cx = cosf(vc.x);
  float sx = sinf(vc.x);
  float cz = cosf(vc.z);
  float sz = sinf(vc.z);
  float sy = -2.0f * (x*z - y*w)
  float cy = (x*4.0f*w - cx*sz + sx*sy*cz) / sz;
  vc.y = asinf( -2.0f * (x*z - y*w) );
  if( cy > 0.0f && sy < 0.0f)
  {
    vc.y = vc.y + PI;
  }
  else if( cy > 0.0f && sy > 0.0f)
  {
    vc.y =  vc.y - PI;
  }

  return vc;
}
[/souce]

The result work but give me some problems.
At an instant i have a rotation (in degree) of (0, -89, 0) when i rotate over y of 2° it give me ( 180, 91, 180 ), this situation is symétric for (0,91,0) and (180, -89, 180).
The problem is that I always correct the z rotation and when ( 180, 91, 180 ) come, i convert the quaternion to ( 180, 91, 0 ) wich is the opposite direction and absolutly false.
Is there a algorithm that give continous values or at least move the problem to another axe or a way to convert GetEulerAngles values ?

Thanx.
  
_______________
Jester, studient programmer The Jester Home in French

Share this post


Link to post
Share on other sites
Advertisement
a) if you go directly from quaternions to transformations matrices, it is not an issue.

b) Successive rotations :
180°X + 90°Y + 180°Z is equivalent to 90°Y
180°X + 89°Y + 180°Z is equivalent to 91°Y
180°X + y° Y + 180°Z is equivalent to 180-y°Y

If all you care about is correctess then it works fine,
if you care about the values...
ben désolé mon vieux, mais tu l'as dans le chou...
unless you apply the transformation implied above.

Interpolation is ok with quaternions though.


Edited by - Fruny on February 23, 2002 9:58:20 PM

Share this post


Link to post
Share on other sites
What are you trying to do exactly ? An arcball interface ?
Why do you care so much about the exact values ?
Why can''t you apply the appropriate transformation of the return values when two of them are 180° ?

Share this post


Link to post
Share on other sites
I was trying to get the z rotation value to generate a quaternion to annul this component. But today I''ve implement another technique (using local axis) that generate a good FPS camera (no z rotation).
Now know the exact rotation is just for information.

Why can''t you apply the appropriate transformation of the return values when two of them are 180° ?
I''m working in a 3D, and it work only in 2D(perpendicular to an axe).

_______________

Jester, studient programmer
The Jester Home in French

Share this post


Link to post
Share on other sites
If you want to kill the rotation around an axis (e.g. Z ) and you have a quaternion representing that rotation, just kill the corresponding coordinate (z=0) and renormalize the quaternion.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Fruny - I have heard people on message boards say this (just kill the z-component or whatever), and I haven''t tried it myself, but it seems a little bit ... wrong.

For sure, you get *a* rotation that has no z-component, but it isn''t the "same" rotation in any meaningful way with respect to magnitude... In fact the magnitude of your resulting rotation is guaranteed to be the same as that of the original rotation (since the cos(theta) term of the quaternion does not change), when the natural thing to expect of a "rotation with part of some original rotation removed" is a rotation of lesser magnitude. Ya know what I''m saying?

In fact, if you factor a quaternion into (rotation around some vector in the XY plane) times (rotation around Z), and then kill the Z part, you don''t get the same answer as if you just zero the z-component. Yet arguably this answer is "more correct". (I use this factorization in next month''s gdmag actually).

Can you spot me a reference that has anything to say about the rotation you get from zeroing some component being meaningful with respect to the original rotation?

- Jonathan.

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
If you want to kill the rotation around an axis (e.g. Z ) and you have a quaternion representing that rotation, just kill the corresponding coordinate (z=0) and renormalize the quaternion.


It only work for small angle. I not found the correct sources I''ve read it sorry. It probably work for some implementation and not for other.

_______________

Jester, studient programmer
The Jester Home in French

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
Fruny - I have heard people on message boards say this (just kill the z-component or whatever), and I haven''t tried it myself, but it seems a little bit ... wrong.
(...)



Ok, I have no justification beyond my own visualisation of the thing. I cannot quite visualise for 1 coordinate, so I''ll show for two : keep only the Z rotation to move point A to point B.

Visualize the rotation in space as the wedge formed by AOB where O is the origin. If you project it on the plane (xOy) (i.e. transform it into a rotation around the Z axis), you will notice that the angle (OA'',OB'') is larger than the angle (OA,OB).

The rotation involves a larger angle and arccos is monotonously increasing. So it makes sense that the w-coordinate would become larger (in absolute value) when you renormalize after canceling coordinates.

And the math seems to work out fine (though I haven''t re-derived it myself, from the projections and everything) : this is the technique that the arcball interface uses, keeping two axes of rotation to move the ''trackball'' in which the object is embedded according to the motion of your mouse cursor on the screen. I haven''t tried in another setting (which is why I asked), so I can only presume.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hmm, okay, I have to think about this. But I''m confused, as it seems to me that the angle between OA'' and OB'' will always be smaller than, or equal to, the angle between OA and OB... not larger than it. The only way I know of to get a larger angle is by non-orthogonal projection, which is not what you''re talking about ... right?

But again, I could easily just be interpreting your explanation wrong. I''ll think about it some.

-Jonathan.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!