There are a lot of materials out there talking about quaternions, and most of you are already familiar with them, but I thought I will add a small piece from myself, and explain how I do look at them.
So, what they are? I like to describe them as :
4 dimensional numbers describing 3d rotation in space.
There is some history how they were invented by William Hamilton and what else they are being used for, but for now, I want to limit this post just to the absolute minimum to understand what they do in your game.
Let’s look at the formula describing quaternion :
a + bi + cj + dk
a,b,c,d are real numbers – these are the numbers you are most likely well familiar with.
i,j,k are imaginary numbers ( a little bit unfortunate naming ), to ease the pain of understanding them, think about them as the next category of numbers. Similar to negative numbers, fractions, etc. Another group of numbers we can use. In case of a quaternion, these 3 are referred as fundamental quaternion units.
There are interesting properties behind Mr. Hamilton discovery :
i^2 = j^2 = k^2 = ijk = -1
and I would highly encourage you to dig in a little bit more into the math behind it, to get a full grasp on what is going on under the surface…
For now though, since you know a little bit of theory, how do you create a quaternion knowing the rotation in 3d space you want to achieve?
To create a quaternion you will need to two variables, an angle (in radians) describing the rotation and a vector describing axis it is rotated along. Then you can fill it with the following formula: X,Y,Z,W
Angle in Radian = Angle in Degree / 360 * PI * 2;
X,Y,Z = AxisInfo * sin ( theta / 2)
W = cos ( theta / 2)
That will define a rule where X^2 + Y^2 + Z^2 + W^2 = 1
Quaternion length is 1.
Multiplying two quaternions will result in one quaternion with the length of 1.
A P B
Linear interpolation : p = A + t * (B-A)
Applying the same to the quaternion will change the magnitude of the quaternion. Therefore we do want to use Slerp :
A P B
To start SLERP interpolation, we need to find out what quaternion allows us to rotate from A to B, so B = X * A where X is an unknown quaternion we need to figure out. Having :
B = X * A
we can try to multiply both sides by inverted quaternion A will give us :
B*invertedA = X
At this point, we could do t * (B*invertedA), but that will result in a quaternion having an incorrect magnitude (remember the rule from above). So instead of multiplying the whole quaternion by t, we can look into how the quaternion is created, and recreate it with interpolated angle value it takes.
Based on the definition previously mentioned, it would be :
X,Y,Z = X.AxisInfo * sin ( t * theta / 2)
W = cos (t * theta / 2)
newRotation = (X,Y,Z,W)
That will result in a quaternion describing the rotation from A to B by t, so to finalize it we have to do newRotation * A, and that gives us P.