Moussa Dembélé – www.mousman.com- firstname.lastname@example.org
When dealing with 3D rotations, 3 choices can be made : use of Euler angles, use of axis angles, use of quaternions.
Rotation with Euler angles should be avoided and if you have any doubts about that read this article : Euler angles are evil.
For those who don’t want to read the link, the main thing to know is that euler angles have two really bad downsides :
the gimbal lock effect and roundoff error which may lead to distortions.
So remains two choices.
Why or when choose one or the other is the purpose of this article.
Quaternions are quiet a piece of mathematics but luckily we don’t have to fully understand them in order to use them.
They are to 3D what complex numbers are to 2D that is to say that they contain 3d space data and are numbers.
And because they are numbers we can do mathematical operations with them.
A quaternion can be represented as q = w + xi + yj + zk where w is a real number, and x, y, and z are complex numbers.
Amongst all quaternions one particular quaternion has our attention : the unit quaternion.
This quaternion can be seen as an orienation where x, y, and z represent an axis and w represents an angle of rotation.
One mathematical operation has also our attention : the multiplication.
The nice thing with unit quaternions is that multipying two unit quaternions will give a unit quaternion combining the rotations of the two quaternions.
Which is perfect for 3d rotation.
(off course multiply quaternions is not as simple as mutliply real numbers but still easy).
In as3 we can get a unit quaternion from a matrix3D using decompose(Orientation3D.QUATERNION).
This method return a vector of three Vector3D : the first one about translation, the second one about rotation (our quaternion) and the third about scale settings.
We have then to define a second quaternion corresponding to the rotation we want to apply.
Multiplication of the second one by the first one (order matters) will give us a third unit quaternion combining the rotations.
A call to Matrix3D.recompose(
components:Vector.<Vector3D>,Orientation3D.QUATERNION) will build the new matrix3D to use.
( you will find an exemple in my next post).
Using axis angles is much simpler to understand.
It is to define an axis of rotation and a angle for this rotation.
Nice and easy !
So why not always use axis angles ?
There is a downside when using them :
doing interpolations based on axis angles won’t lead to nice and smooth transitions.
Quaternions are much more convenients for that : see SLERP for more informations.
I’ve made three simulated uses of arcball implementations.
The first one using axis angles,
The second one with quaternions , using decomposistion and recomposition with each update of the arcball call,
the third one with quaternions, using decomposition only on a mouseDown event and recomposition with each update of the arcball. (less safer if the 3d model is rotated or moved somewehere else in the application).
The results are almost the same (I’ve had to make 100 000 iterations on each update call to see a difference).
on my computer the scores are (with 100 000 iterations) :
- quaternions using decomposition only on a mouseDown : 420 ms
- axis angle : 532 ms
- quaternions : 669 ms.
Depending on what you want to do you may choose axis angles or quaternions.
In my implementation of arcball and orbital camera I’ve choosen axis angle due to the (slightly) gain of performance.
I will talk about arcball and orbital camera in my next post.
Any question any comments, don’t hesitate.