quaternion rotation
quaternions have been plaguing my mind for months and their mystery has eluded me till now… finally figured the sucker out.
in short, they allow for intuitive rotation around each axis.
normally if you rotate around one axis and then around another, you get a combination of those two rotations and its not really where you want to be.
quaternions allow to rotate around each axis without effecting the rotation of the other axis, so imagine a orientating a aeroplane model in a 3D flying game…
an aeroplane can be rotated around each axis and these angles are referred to as roll (x-axis), pitch (y-axis) and yaw (z-axis).
roll is then the aeroplane direction moving up and down.
pitch is the aeroplane direction moving left to right.
and yaw is the aeroplane swaying from side to side.
so finally worked out the mathematics behind this by reverse engineering some existing arcball code.
below is the processing implementation done with pure opengl, it is using some handy classes in toxi’s geomutils.
the steps are,
1) work out the rotation vectors around each axis, simply by rotating the vector around an axis.
2) work out the rotation quaternion for each axis, by getting the dot and cross product of each rotation vector from its origin.
3) multiply the rotation quaternions of each axis. – this will give you the overall rotation quaternion.
4) convert the rotation quaternion into a matrix and apply that rotation matrix.
5) draw your aeroplane! done.
float DEGTORAD = PI / 180;
Vec3D xrot, yrot, zrot;
Quaternion xrotQuat, yrotQuat, zrotQuat, rotQuat;
Matrix4x4 m;
float angleX, angleY, angleZ;
angleX = angleDegreesX * DEGTORAD;
angleY = angleDegreesY * DEGTORAD;
angleZ = angleDegreesZ * DEGTORAD;
xrot = Vec3D.Z_AXIS.copy().rotateX( angleX );
yrot = Vec3D.X_AXIS.copy().rotateY( angleY );
zrot = Vec3D.X_AXIS.copy().rotateZ( angleZ );
xrotQuat = new Quaternion( 1, new Vec3D( 0, 0, 0 ) );
xrotQuat.set( xrot.dot( Vec3D.Z_AXIS.copy() ), xrot.cross( Vec3D.Z_AXIS.copy() ) );
yrotQuat = new Quaternion( 1, new Vec3D( 0, 0, 0 ) );
yrotQuat.set( yrot.dot( Vec3D.X_AXIS.copy() ), yrot.cross( Vec3D.X_AXIS.copy() ) );
zrotQuat = new Quaternion( 1, new Vec3D( 0, 0, 0 ) );
zrotQuat.set( zrot.dot( Vec3D.X_AXIS.copy() ), zrot.cross( Vec3D.X_AXIS.copy() ) );
rotQuat = xrotQuat.multiply( yrotQuat ).multiply( zrotQuat );
m = rotQuat.getMatrix();
FloatBuffer rotMatrix;
rotMatrix = ByteBuffer.allocateDirect(4 * 4 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
rotMatrix.put
(
new float[]
{
(float)m.matrix[0][0], (float)m.matrix[0][1], (float)m.matrix[0][2], (float)m.matrix[0][3],
(float)m.matrix[1][0], (float)m.matrix[1][1], (float)m.matrix[1][2], (float)m.matrix[1][3],
(float)m.matrix[2][0], (float)m.matrix[2][1], (float)m.matrix[2][2], (float)m.matrix[2][3],
(float)m.matrix[3][0], (float)m.matrix[3][1], (float)m.matrix[3][2], (float)m.matrix[3][3]
}
);
rotMatrix.flip();
gl.glPushMatrix();
gl.glTranslatef( loc.x, loc.y, loc.z );
gl.glMultMatrixf( rotMatrix );
gl.glTranslatef( -loc.x, -loc.y, -loc.z );
// draw here.
gl.glPopMatrix();
About this entry
You’re currently reading “quaternion rotation,” an entry on julapy
- Published:
- 12.22.08 / 12pm
- Category:
- code, opengl, processing


















2 Comments
Jump to comment form | comments rss [?] | trackback uri [?]