Finding which is the shorter 2D angle

Calculating the shorter angle of rotation in 2D

Here’s a really simple math problem in 2D games development that has a surprisingly complex solution. If I were to give you angles a and b, how would you calculate 1) the direction — that is, clockwise being positive; and anti-clockwise being negative — and 2) magnitude of the shorter angle of rotation from a to b?

Main angle question
We want the angle in green.

When you visualise it, both values seem so obvious; which was why I was so surprised I couldn’t figure it out. On the surface, it seems really simple — if you just take b – a, doesn’t it give you the solution?

(What looks like) the solution

Here’s an example that illustrates how taking b – a can work:

If we let a = 150° and b = 170°, b – a = 170° – 150° = 20°

The case above demonstrates that for the rotations pictured below, the formula correctly gives us a counter-clockwise rotation of 20° as the shorter angle of rotation.

Example 1
a needs to rotate 20° (i.e. counter-clockwise) to get to b.

Conversely:

If we let a = 150° and b = 140°, b – a = 140° – 150° = -10°

The case above demonstrates that for these other rotations pictured below, the formula correctly gives us a clockwise rotation of -10° as the shorter angle of rotation.

Example 2
a needs to rotate -10° (i.e. clockwise) to get to b.

Article continues after the advertisement:

Save Soil

The Save Soil Movement

Poor farming practices and policies across the world have led to the degradation of agricultural soils in the world. This has led to the loss of nutritional value in our food over the years, and it will affect our food production capabilities in the coming decades.

Learn more about Save Soil →


The problem with angular values

When you begin to dig deeper, however, you will quickly find that things can get surprisingly complex problem for 2 reasons:

  1. Angles loop around beyond 360°, so if a = 380° and b = 40°, we get 340° as the shorter angle of rotation. This is obviously wrong, because the shorter angle of rotation is never larger than 180°.
  2. In most (i.e. 99%) game engines, the lower half of the circle goes from 0° to -180°, like radians do (refer to the picture below). Hence, if we were to consider cases like a = 160° and b = -160°, we will get 320° as the shorter angle of rotation.
Positive and negative angles
If measured in radians, 180° will be π.

The (actual) solution

Well, a – b actually works. Once you convert the result so that it is between -180° and 180° (or -π and π), that is. Here’s how you convert any angle into a value between -180° and 180°:

  1. Firstly, if your result is already between -180° and 180°, then you ignore the following steps.
  2. Next, convert your result into an angle between -360° and 360°. All you have to do is to modulo the result with 360, i.e. result % 360.
  3. Finally, if your result is less than -180°, add 360° to it; otherwise, if it is more than 180°, subtract 360° from it.

Or, in short, expressed mathematically:

f(x) = { sgn x × 360° – |x| if |x| > 180 x if 0 ≥ |x| ≤ 180

If that is hard to read, here’s a code snippet in C# that expresses the same thing:

float result = b - a; // Shorter angle of rotation.

// If our result's value is more than 180 or less than -180.
if(Mathf.Abs(result) > 180)
	// Covert the value to be between -180 and 180.
	result = -Math.Sign(result) * (360 - Math.Abs(result));

Conclusion

Did the article help you figure out your angles? Or maybe you spotted some errors with our math? Feel free to leave us a comment below.


Article continues after the advertisement:

Save Soil

The Save Soil Movement

Poor farming practices and policies across the world have led to the degradation of agricultural soils in the world. This has led to the loss of nutritional value in our food over the years, and it will affect our food production capabilities in the coming decades.

Learn more about Save Soil →


There are 3 comments:

  1. Thanks for the article! Minor nit: in step 3, you say “Finally, if your result is negative, add 360° to it; otherwise, subtract 360° from it.”. This should say “if your result is higher lower than 180°, add 360° to it; if it is higher than 180°, subtract 360° from it.”

    This is what the rest of the article does, and is the correct thing to do. It’s just a typo in the prose that threw me off.

Leave a Reply

Your email address will not be published. Required fields are marked *

Note: You can use Markdown to format your comments.

For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

I agree to these terms.

This site uses Akismet to reduce spam. Learn how your comment data is processed.