I have a sprite that moves from waypoint to waypoint. It turns to face its velocity vector, but not instantly (there's a rotation speed).

The problem I'm having is, from one direction to another, the sprite will often turn in wild, unnecessary ways instead of appearing like you might expect a car to appear (turn such that the minimum delta in angle occurs).

Right now I'm using the following formula to calculate the rotation float for the current velocity:

MathHelper.PiOver2 + -Math.Atan2(anotherVector.Y - vector.Y, -(anotherVector.X - vector.X));

And then I lerp the current rotation by the new rotation by the rotation speed (10f):

rotation = MathHelper.Lerp(rotation, targetRotation, 10f * (float)gameTime.ElapsedGameTime.TotalSeconds);

But unfortunately, it's causing the sprite to spin in wild directions before reaching the correct angle. Any suggestions?

  • \$\begingroup\$ Shouldn't the 3rd parameter for lerp, the time, be between 0 and 1? \$\endgroup\$ Jul 16 '11 at 18:41
  • 1
    \$\begingroup\$ possible duplicate of Calculating angle between 2 vectors \$\endgroup\$
    – user744
    Jul 18 '11 at 15:37

This is due to the angle wrapping. For example, lerping from 1 degree to 359 degrees is not what is wanted, instead the equivalent lerp from 1 degree to -1 degree should be used. If the angles are in the same range, then adding or subtracting 2*pi to the target will work, e.g.

if (targetRotation > rotation+Pi)
    targetRotation -= 2*Pi;
else if (targetRotation < rotation-Pi)
    targetRotation += 2*Pi;

It's important that the angles are in the same range. The [-pi,pi] range returned by atan2 is the most standard, so I'd recommend using that for all angles if possible. Whatever range is chosen, wrap the rotation back into that range after lerping.

  • 4
    \$\begingroup\$ The function MathHelper.WrapAngle is useful for this. \$\endgroup\$ Jul 16 '11 at 9:58
  • \$\begingroup\$ I think you should replace the ifs with whiles. what if one of them is 100040 degrees and the other is 10? \$\endgroup\$ Jul 27 '16 at 10:27

You must log in to answer this question.