Tuesday, 3 January 2012

Trig-free rotation blending

As mentioned yesterday complex numbers can be used to do rotations in two dimensions, by just multiplying by a suitable (complex) value. One particular application is rotation blending or interpolation, where the direction of something is blended smoothly over time. An example would be aiming a gun, where having it move over time to aim is more realistic and interesting.

Normally this would be done by blending angles, so an angle is updated in steps from one direction to another. But this is expensive as two trigonometric calculations are required each frame to update the direction or to transform whatever is being rotated. It is quicker to use complex numbers and avoid trigonometry altogether, except at the start.

This is done by generating a 'step' complex number to replace the angle step, based on the change in angle each frame. Then instead of adding the angle this step complex number is multiplied by the current direction to incrementally rotate to the new direction, for as long as it takes to reach it.

If the rotation speed is constant the 'step' can be pre-calculated, although care needs to be taken if the rotation can take place in two directions, i.e. clockwise and anticlockwise. The step complex number can be conjugated to deal with this. However it is done the result of initial calculations should be a complex value which is used to update the rotation like so:

function UpdateAim():void {
    var fR:Number = r1, fI:Number = i1;
    r1 = fR * rStep - fI * iStep;
    i1 = fI * rStep + fR * iStep;
    RotateGun(r1, i1);

This is simply complex multiplication, done each frame to update the number (r1, i1) and so the direction. It is short and easily inlined where needed.

I have done another version of my ballistics app implementing this, embedded below. It is a little simpler than the previous version as it now only has one missile and path. This makes the code and behaviour clearer, especially as it's difficult to do classes in wonderfl. In a real application the gun would have its own class, so adding another gun would be just a single line.

No comments:

Post a comment