Jump to content
  • Advertisement
Sign in to follow this  
leiavoia

Angle wrapping

This topic is 3653 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[I've implemented a lame version of this already, but i'm hoping to get a better version from you fine folks.] What's the simplest method for finding the difference between any two angles? I've been building a simple euler-angle based 3D camera (i haven't learned about quaternions yet, so i have to use what i know) and i ran into this issue. Obviously, 95 is 5 away from 90 degrees ( 95-90=5 ), but that doesn't apply to numbers that wrap around the 360 or 0 mark. I feel like the code i wrote is too much for what should be a simple operation. Can you do this any simpler than i did it? Thanks!
// checks to see if two angles are within "range" of each other
// assume angles are clamped 0-360;
bool Camera::AngleInRange( float a, float b, float range ) {
	if ( a > b ) {
		float temp = b;
		b = a;
		a = temp;
		}
	a += 360;
	b += 360;
	if ( b - a > 180 ) { a += 360; }
	return ( b > a - range && b < a + range );
	}

Share this post


Link to post
Share on other sites
Advertisement
I like to use a straight 16 bit integer for my angles, rather than float. It has some very convenient properties for the kind of angle operations needed in most games.

First, treat 65536 as the number of degrees in a full revolution. The 16 bit value only goes up to 65535, so that way if you go over, it naturally wraps back to 0.

Second, if you cast the unsigned short value to a signed short, you magically have the same angle represented as -180 to +180 degrees.

Third, you can subtract 2 angles, and due to the natural wrapping, the signed representation is the shortest angular distance between them. You can take the absolute value of that if needed, too.

There are a few caveats though:

1. Don't do a for loop comparing an angle with 360 degrees as the ending condition, since 360 is actually the same thing as 0. Use a different loop variable instead.

2. The absolute signed difference has one ambiguous value at precisely -180 degreess, where abs(-32768) becomes 32768, which when treated as a signed 16 bit value is still negative. One solution is to check for it and return 32767 instead. Or if you're more disciplined, just be sure to always treat it as unsigned after doing absolute value.

3. It takes a while to wrap your head around and learn to use effectively, so some programmers will get confused and hate you at first.

4. You may feel compelled to write comparison operators for your angle class. Don't do it. It depends on context wether you want to compare the signed or unsigned representation, or even signed against unsigned, so the operators will inevitably be wrong in some cases. Better to always compare the raw values explicitly the way you want to.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!