Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with Angle Wrap in c++ code

Tags:

c++

math

Is there a way to safety and simply deal with angle wrap with the minimum number of case statements.

Angle wrap occurs when using a particular representation for angle (either 0-360 deg or -180 - 180 deg (or equivalent in radians)) and you wrap over the angle. For example say you have an angle of -170, and you subtract 50 deg. You mathematically add up to -220 but should actually be +140 deg.

Obviously you can check for this using:

if (deg < -180) { 180 - abs(deg + 180); } 

or similar. But firstly you need multitudes of checks and secondly it doesn't work if you wrap twice.

The second case where this is prevalent is in the interpolation between two angles.

For Example, say I have an angle of -170 deg and 160 deg and I want halfway in between them. A common way to do this is ang1 + 0.5(ang2-ang1) but in the example i have provided it will cause the angle to be -5 deg when it should be 175.

Is there a common way to handle angle wrap in these scenarios?

like image 797
Fantastic Mr Fox Avatar asked Jul 16 '12 04:07

Fantastic Mr Fox


People also ask

What is angle normalization?

A normalized angle maps the full range of angles (360 degrees) to the range zero to one. The following table shows the relationship between normalized angles and degrees: Normalized. Degrees.

How do you wrap an angle in Matlab?

Wrap Angles to Pi Radians Wrap the angles to the range [- π , π ] radians. Specify a second list of angles, and wrap them. lambda2 = -10:0.1:10; lambda2Wrapped = wrapToPi(lambda2); Plot the wrapped angles.


1 Answers

For completeness I'll include both [0, 360) and [-180, 180) normalizations.

You will need #include <math.h>.


Normalize to [0,360):

double constrainAngle(double x){     x = fmod(x,360);     if (x < 0)         x += 360;     return x; } 

Normalize to [-180,180):

double constrainAngle(double x){     x = fmod(x + 180,360);     if (x < 0)         x += 360;     return x - 180; } 

The pattern should be easy enough to recognize to generalize to radians.


Angle Bisection:

double angleDiff(double a,double b){     double dif = fmod(b - a + 180,360);     if (dif < 0)         dif += 360;     return dif - 180; } double bisectAngle(double a,double b){     return constrainAngle(a + angleDiff(a,b) * 0.5); } 

This should bisect an angle on the "smaller" side. (warning: not fully tested)

like image 142
Mysticial Avatar answered Oct 01 '22 00:10

Mysticial