# Rotate directly towards a target at a constant speed

I've written a program (see on JS Fiddle) that rotates my player towards the mouse cursor at a constant speed. I've computed the angle to the point using the Math.atan2 function, but when incrementing or decrementing the player's rotation towards that value, it does not always take the shortest path.

This image describes the logic I intend to evaluate:

The problem appears when you cross a specific angle, the player rotates the long way around to reach the cursor, instead of taking the shortest path. How can I always take the shortest path at a constant speed?

Many thanks.

• I tried using a dot product of the player and mouse position but the player just seems to spin, argh. var dot = player.x*-mouse.y + player.y*mouse.x;if(dot > 0){ player.r -= inc; }else if(dot < 0){ player.r += inc; }
– Gaz
Jul 2, 2016 at 14:37

Your main problem is that you did not account for the discontinuity in the arctangent function...

// Check if arctangent has crossed the discontinuity
if (delta < -Math.PI || (delta > 0 && delta < Math.PI)) {


And you are not reducing the player rotation into a canonical -Pi <= x < Pi range.

// Reduce player.r into the -PI thru PI range
player.r = (player.r + 3 * Math.PI) % (2 * Math.PI) - Math.PI;


Additionally, to actually get a fixed rotation speed, you can not rely on the refresh rate of the screen. Instead you must either measure the clock each update, or use an interval timer.

setInterval(update, 1000 / 24); // run update at 24fps to achieve constant rate

• The fixed rotation speed is always achieved without using the setInterval() function. If the game slows down for some reason, the object is still rotating at a speed coherent with the game world logic. Jul 2, 2016 at 16:14
• As I've said, you could measure the clock at each update instead of using an interval timer, but it's more complicated. Such a simple fixed update was natural for this example. The question is about rotating at constant speed, not about synchronizing game logic. Jul 2, 2016 at 16:23
• Many thanks Mick for your advice and guidance despite my incoherent post! I'll get to implementing this in the logic and learning more about the calculations later.
– Gaz
Jul 2, 2016 at 17:02