7
\$\begingroup\$

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?

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

1 Answer 1

6
\$\begingroup\$

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.

\$\endgroup\$
2
  • 4
    \$\begingroup\$ The function MathHelper.WrapAngle is useful for this. \$\endgroup\$ Commented Jul 16, 2011 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\$ Commented Jul 27, 2016 at 10:27

You must log in to answer this question.