Jump to content
  • Advertisement
Sign in to follow this  
Boltimus

Trouble with Quaternions... about to lose all my hair.. please dont let me go bald

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

[size=2]Hello everyone, I'm using jogl and am simply trying to rotate a sphere in all three axes: x, y, and z.

Here is the code that draws the ball, I'll post two other snippets after it...



private void drawBall( GL2 gl )
{

/* now add the texture */
rdsTexture.enable( gl );
rdsTexture.bind( gl );

/* rotate for inclination and toolface */
Quat4f result = this.rotate(roll, pitch, yaw);
result.normalize();
float[ ] modelView = this.quatToMatrix( result );

/* the default view is straight and level */
gl.glMultMatrixf( modelView , 0 );

/* draw a sphere */
GLUquadric quadric = glu.gluNewQuadric( );
glu.gluQuadricTexture( quadric , true );
glu.gluSphere( quadric , 6.0f , 64 , 64 );
}



okay, now here is the code for the this.rotate ...


public Quat4f rotate( double roll , double pitch , double yaw )
{

// Assuming the angles are in radians.
float cY = ( float ) Math.cos( Math.toRadians( yaw ) / 2.0f );
float sY = ( float ) Math.sin( Math.toRadians( yaw ) / 2.0f );
float cX = ( float ) Math.cos( Math.toRadians( pitch ) / 2.0f );
float sX = ( float ) Math.sin( Math.toRadians( pitch ) / 2.0f );
float cZ = ( float ) Math.cos( Math.toRadians( roll ) / 2.0f );
float sZ = ( float ) Math.sin( Math.toRadians( roll ) / 2.0f );

Quat4f q = new Quat4f( );
q.w = cZ * cY * cX + sZ * sY * sX;
q.x = cZ * cY * sX - sZ * sY * cX;
q.y = cZ * sY * cX + sZ * cY * sX;
q.z = sZ * cY * cX - cZ * sY * sX;

q.normalize( );
return q;
}



and finally, the code for this.quatToMatrix ...


private float[ ] quatToMatrix( Quat4f q )
{

float[] matrix = new float[16];

// First Column
matrix[0] = 1 - 2 * (q.y * q.y + q.z * q.z);
matrix[1] = 2 * (q.x * q.y + q.z * q.w);
matrix[2] = 2 * (q.x * q.z - q.y * q.w);
matrix[3] = 0;

// Second Column
matrix[4] = 2 * (q.x * q.y - q.z * q.w);
matrix[5] = 1 - 2 * (q.x * q.x + q.z * q.z);
matrix[6] = 2 * (q.z * q.y + q.x * q.w);
matrix[7] = 0;

// Third Column
matrix[8] = 2 * (q.x * q.z + q.y * q.w);
matrix[9] = 2 * (q.y * q.z - q.x * q.w);
matrix[10] = 1 - 2 * (q.x * q.x + q.y * q.y);
matrix[11] = 0;

// Fourth Column
matrix[12] = 0;
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;

return matrix;
}



[font="Arial"]Here is what is happening ... I can pitch (rotate around x-axis) fine, but if I roll to the right or left by 90 degrees and then pitch, the ball appears to yaw. Does something look amiss here?[/font]

Share this post


Link to post
Share on other sites
Advertisement

[font="Arial"]Here is what is happening ... I can pitch (rotate around x-axis) fine, but if I roll to the right or left by 90 degrees and then pitch, the ball appears to yaw. Does something look amiss here?[/font]


There's probably nothing wrong with your code, but your understanding of 3D rotations needs improvement. The composition of roll and pitch produces yaw, and as long as you try to represent your rotations as roll-pitch-yaw combinations, you'll get the behavior you observe.

What you probably want to do is store the current orientation as a quaternion, and not store roll, pitch and yaw anywhere. You can then multiply the quaternion that represents your current orientation by quaternions that represent small rotations around the axes, according to the user's input. Remember to renormalize the quaternion every now and then (or every frame, since it's cheap).

Share this post


Link to post
Share on other sites

What you probably want to do is store the current orientation as a quaternion, and not store roll, pitch and yaw anywhere.
[/quote]

Ok, let me make sure I got this then.... when I first start up and init, I would just setup a quat that is constructed from basically the identity matrix. then .. (see below)


You can then multiply the quaternion that represents your current orientation by quaternions that represent small rotations around the axes, according to the user's input.
[/quote]


as changes are made in each axis multiply, that current orientation quat by the rotation quat. For example when the user presses the up-arrow key ...I would create a rotation quat around the x-axis for 1 degree of rotation and then multiply it against my master orientation quat and store the value as my new orientation, and then convert it to matrix form where I would multiply it against the ModelViewMatrix?

Share this post


Link to post
Share on other sites


What you probably want to do is store the current orientation as a quaternion, and not store roll, pitch and yaw anywhere.


Ok, let me make sure I got this then.... when I first start up and init, I would just setup a quat that is constructed from basically the identity matrix. then .. (see below)[/quote]

So far, so good. The quaternion constructed from basically the identity matrix is more commonly referred to as "one". :)


You can then multiply the quaternion that represents your current orientation by quaternions that represent small rotations around the axes, according to the user's input.
[/quote]


as changes are made in each axis multiply, that current orientation quat by the rotation quat. For example when the user presses the up-arrow key ...I would create a rotation quat around the x-axis for 1 degree of rotation and then multiply it against my master orientation quat and store the value as my new orientation, and then convert it to matrix form where I would multiply it against the ModelViewMatrix?
[/quote]

Yup, I think you got it. But, as I said earlier, you should probably renormalize the quaternion after you modify it. This is as simple as scaling it by a factor of 1/sqrt(w^2+x^2+y^2+z^2). Otherwise little precision errors will accumulate and eventually it will become apparent that the quaternion no longer represents a rotation, since it doesn't have unit length.

Share this post


Link to post
Share on other sites
Alvaro!!! thanks so much!!!! that was it.. I could not believe how easy it was to do. It was right under my eyes, I just wasn't looking at it the right way. Once again, I and my scalp thank you! :)

Share this post


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

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!