Here we'll cover the basics of Euler Angles, gimbal lock, quaternions and rotation matrices.

Euler angles are the most intuitive way of representing rotation. They are made of three seperate angles, given as (x,y,z). We can use them to specify any orientation or rotation amount in 3D space. In MathHelper, we name the angles pitch, yaw and roll. These terms are taken from flight dynamics, and make the angles easier to visualize.

**Pitch**: the angle at which the plane is climbing**Yaw**: the direction the plane is travelling**Roll**: the tilt of the plane's wings (ie, one wing is lower than the other)

In the Math and Quaternion FAQ, I found: "Mathematical convention requires that a positive rotation angle generates a clockwise rotation when looking from the origin towards the positive end of the rotation axis." This is the way MathHelper's Euler Angles are implemented. Imagine you have a coordinate system where x increases to the right, y increases upwards, and z increases forwards (into the screen):

A positive amount of yaw (along the y axis) creates a rotation in the direction specified by the brown circle. If were were at the bottom of this picture, looking up along the y-axis, we would see that the circle rotates in a clockwise direction.

Unfortunately, there's no real pre-set agreement on what the (x,y,z) of a Euler Angle should represent, or in which direction we should rotate in. If you encounter Euler Angles that were calculated with other systems, you will probably have to convert them to MathHelper's convention before they can be used.

Imagine you have an object that you would like to rotate on-screen. You have the object's current orientation (A), and the orientation you'd like it to end up facing (B). To show a smooth animation we need to calculate many intermediate orientations that form a 'rotational path' between A and B. We would then draw the object at each orientation in the path, to show it turning towards the final orientation.

Sound good? The problem is that using Euler Angles alone will often create strange, jerky motion with sudden unexpected changes in direction. This is due to Gimbal Lock, which happens when one angle is rotated to be parallel to another:

In this graphic, the pitch is modified until the plane is facing straight up. (Pitch is parallel to yaw). Now, changing either yaw or roll gives us rotation along the same axis! We've lost a degree of freedom, and can only change the plane's pitch and roll. When this happens, we get a strange jump in our animated rotation, as the gimbals from the picture suddenly flip to new positions. The object will continue rotating towards the desired orienation, but from a different starting point.

A Quaternion represents an orientation in space, similar to a Euler Angle. However, Quaternions let us make smooth rotational animations, and are not susceptible to Gimbal Lock. They have four components, written as (w,x,y,z). The exact details of how Quaternions actually work are quite complex. We can think of a Quaternion as a 'black box' where Euler Angles go in, and smooth rotations come out without needing to understand the inner workings.

Say we have two Quaternions, A and B. We'd like to draw an object that's facing in direction A, and smoothly rotate it to face towards B. This is where SLERP comes in - it rotates A a fraction of the distance towards B. SLERP takes four parameters:

- The
**initial**quaterion. - The
**destination**quaternion. - The amount of
**rotational distance**to cover, given as a number between 0 (returns the initial quaternion) and 1 (returns the destination). - The
**type**of SLERP to perform - we can choose to follow the shortest path (rotation <= 180 degrees) or the longest path (rotation >= 180 degrees)

And that's it! If we wanted to show 100 frames of animation, we would perform a SLERP 100 times, each time incrementing the rotational distance by 0.01.

Rotation Matrices do the math to actually perform the rotation. We can convert a Euler Angle or a Quaternion into a rotation matrix, which can then rotate a point by the specified amount. The matrix is a 3x3 grid of floating-point numbers. There are also 4x4 matrices that will do rotation and translation in a single operation, but here we'll stick to rotation alone.

A rotation matrix takes a single point in 3D space, and rotates it by the amount in the Euler Angle or Quaternion we used to generate the matrix. To rotate a 3D object made up of lines and vertices, we would apply the rotation matrix to each vertex individually, then redraw the lines connecting them.

The origin is given as the point at (0,0,0) in the 3D space. Whenever a point P is rotated, it travels a given distance around the origin. Imagine a sphere that's centered on the origin. The sphere's radius is equal to P's distance from the origin. When we rotate P by Θ degrees, it moves along the sphere's surface in the direction of the rotation.

Most of the time, we'd like to rotate points around some coordinates other than the origin. For example, say we want to make a cube spin. Each of the cube's vertices should be rotated around the cube's center point by some amount, even if the cube is not centered on the origin. For each vertex in the cube, we would perform the following operation:

- Translate the vertex to the origin. This can be done by subtracting it by the cube's center position. Eg, if the cube is centered on (5, 10, 20), we would subtract 5 from the vertex's x-coordinate, 10 from the vertex's y-coordinate, and 20 from the vertex's z-coordinate.
- Perform the rotation with a rotation matrix.
- Translate the vertex back to the cube's position. We undo the first step, and add 5, 10, and 20 to the vertex's coordinates.

Here's a quick summary of the steps needed to rotate a 3D point.

- Calculate the rotation matrix that represents the rotation. We can convert Euler Angles and Quaternions into matrices.
- Translate the point to the origin.
- Use the matrix to perform the rotation.
- Translate the point back to its object-coordinates.

Remember, to perform smooth rotations, we need to represent the object's starting orientation and final orientation as Quaternions, and interpolate between them.

Happy Coding!

-David

The images in this document are provided under the following license. See creativecommons.org for a complete license description.

This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license.

- You are free:
- to share - to copy, distribute and transmit the work
- to remix - to adapt the work
- to make commercial use of the work
- Under the following conditions:
- attribution - You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
- share alike - If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one.