When a sprite is rotating to follow an angle, how to prevent it from reversing direction after a point?

Below is a section of my code which handles a player’s sprite rotating towards an angle after a user touches the screen:

touchState = TouchPanel.GetState();
Vector2 touchPosition;

if (touchState.Count > 0)
   touchPosition = new Vector2(touchState[0].Position.X, touchState[0].Position.Y);
   targetPosition = Math.Atan2(player.Position.X - touchPosition.X, player.Position.Y - touchPosition.Y);

if (angle_radians < targetPosition)
    angle_radians += 2 * fps;

if(angle_radians > targetPosition)
    angle_radians -= 2 * fps;

player.Angle = angle_radians * -1;

The problem I’m having is that when the angle goes past a certain point (I believe 3.15 radians?), the logic no longer functions correctly and the sprite reverses direction in a 360 circle until it meets the target position again.

I know there is something I’m missing from this logic, and I can see the problem, but I’m not sure how to approach handling it.

How would I prevent the sprite from reversing direction?


Atan2 returns a value in the range [-pi, pi]. You should account for that by checking what the shortest turn is instead of simply doing a comparison. The best way to check that is to check the sign of the z-component of the cross product (sometimes people call this the 2D cross-product). With how the axes are set up in MG, a positive cross product means you have a clockwise turn (meaning the turn from the first to the second vector will be shortest in the clockwise direction) and a negative cross product means a counterclockwise turn.

public static float Cross(Vector2 v1, Vector2 v2)
    return v1.X * v2.Y - v1.Y * v2.X;

var targetVec = new Vector2(Math.Cos(angle_radians), Math.Sin(angle_radians));
var touchVec = new Vector2(touchState[0].Position.X, touchState[0].Position.Y); 
var dir = Math.Sign(Cross(touchVec, targetVec));
angle_radians = MathHelper.WrapAngle(angle_radians + dir * 2f); // you don't necessarily have to wrap the angle