0

I'm working on a game where the input is done via a joystick. Normally, one would snap the players rotation to the angle that the joystick is pointing, but for my game's purpose, I have to lerp to the value to give a smooth animation. My joypad angles are calculated as follows:

  1. 0 - left
  2. 90 - front
  3. 180 - right
  4. 270 - back

An example of my problem would be: I'm pointing joystick 'front-left'(45 degrees), then I move it 'back-left'(315 degrees), instead of doing the hoped for simple anticlockwise rotation, it rotates clockwise to the value.

I understand why it happens, but I just don't have an idea how to solve this problem. I'd greatly appreciate any input, doesn't have to be code.

thatGuy
  • 25
  • 5
  • If I understand you correctly, the rotation happens but it does not happen on the shortest direction if that direction passes through the zero-degree point? – Philipp Oct 12 '21 at 11:28
  • I think it would be easier to help you if you showed us your code for calculating the rotation. – Philipp Oct 12 '21 at 11:29
  • Yes! I had the idea to just subtract 360 if the angle difference was too much. But I found it to be inaccurate and an unnecessary computation. because the player might rotate clockwise instead giving the same problem. – thatGuy Oct 12 '21 at 11:32
  • 1
    I'm pretty sure we have a question about shortest-direction angle interpolation somewhere here, but my search skills are currently failing me... This question about finding the signed shortest difference between two angles might be helpful though, as this will give you the direction to interpolate to: https://gamedev.stackexchange.com/q/4467/35344 –  Oct 12 '21 at 11:33
  • @Philipp ill update it to the answer – thatGuy Oct 12 '21 at 11:33
  • @Tyyppi_77 I just checked the link you sent and it seems to be exactly what I want. I'm not sure why I couldn't find it before. Revising the code and then ill accept an answer – thatGuy Oct 12 '21 at 11:38
  • 1
    Let's close this as a duplicate of Comparing angles and working out the difference, then. – Philipp Oct 12 '21 at 11:40
  • @Philipp Yes! It's exact! Thank you all for your help – thatGuy Oct 12 '21 at 11:42

1 Answers1

1

You can do this with an angle difference function:

// Remaps angles into [0, 360) range on degrees.
float NormalizeAngle(float angle) {
    return angle - floor(angle / 360f) * 360f;
}

// Returns the shortest signed angular delta // from angle from to angle to, in degrees. float AngleDifference(from, to) { // Wrap difference into [0, 360) range. float difference = NormalizeAngle(to - from);

// Remap to range (-180, 180]
// so that angles more than a half turn away
// go via the shorter route.
if (difference > 180) difference -= 360f;

return difference;

}

// Linearly interpolates between two angles, // using interpolation weight blend in [0, 1]. // Return is normalized into [0, 360) range. float LerpAngle(from, to, blend) { float difference = AngleDifference(from, to);

return NormalizeAngle(from + blend * difference);

}

thatGuy
  • 25
  • 5
DMGregory
  • 134,153
  • 22
  • 242
  • 357