I'm currently in the process of making a 3d "semi" top down game, the camera comes in at a very high angle near 90 to show off the 3d models. I have a main character which can move in 4 axis (up, down, left right) using the arrow keys. I'm trying to create a smooth rotation between each of the axis so that when you press right when the character faces up, his rotation just doesn't jump.

Rotations seem to be weird and I don't quite understand why MathHelper.ConvertToDegrees or Radians doesn't quite give me what I want. When I try to rotate the model, I am translating it back to the origin, rotating then translating back for my order of matrices.

Although what I've found is that for rotation in the Z-axis, 0f seems to be down, 1.6f seems to be right, 3.2f seems to be up and 4.8f seems to be left. So to translate smoothly what I do is say I'm facing up (3.2f) and I want to face, right: Rotation.Z > 1.6 so, while it's greater keep subtracting 0.08f until we reach 1.6 or lower. This works well.

BUT my problem lies in since down is 0 and left is 4.8, when you're facing left and want to face down, you rotate clockwise all the way back to down instead of the logical counter-clockwise. This only happens in left to down or vice versa.

I've thought long and hard about this, down can also be expressed by 5.4f I assume but that doesn't really solve my problem. The approach for going down looks like this:

    else if (currentKeyState.IsKeyDown(Keys.Down))
        //Rotate character to face this direction
        if (rotation.Z != 0)
            if (rotation.Z < 0)
                rotation.Z += 0.08f;
            else if((rotation.Z > 0))
                rotation.Z -= 0.08f;

Since for the left rotation, the rotation.Z value will be 4.8, then by this logic it'll going counter-clockwise. It's probably a simple solution but it has me stumped and one of my biggest problems is not moving on until a problem is fixed even if the game still works.

I've attached a picture of the axis just in case my post is nonsensical:

Axis Rotation

Look forward to any potential solutions.


1 Answer 1


Looks like you're working in radians, so...

  • up = +/- pi
  • left = -pi/2 = 3pi/2
  • right = pi/2 = -3pi/2
  • down = 0 = +/-2pi

(modulo 2pi)

To get the smallest difference between two input angles, you can use something like...

(disclaimer - this is back-of-napkin, so check it in case I flipped a sign that didn't show up in my pencil test cases)

// Returns the shortest angle from start to end
float AngularDelta(float startAngle, float endAngle)
  float delta = endAngle - startAngle;
  delta = ((((delta + pi) % 2pi) + 2pi) % 2pi) - pi

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .