Dealing with Angle Wrap in c++ code
I find using remainder()
from the math library is convenient. Given an angle a
, to constrain it to -180, 180 you can just do:
remainder(a, 360.0);
and change the 360.0
to 2.0 * M_PI
for radians
Normalise an angle to range [-180, 180)
deg -= 360. * std::floor((deg + 180.) * (1. / 360.));
Normalise an angle to range [0, 360)
deg -= 360. * std::floor(deg * (1. / 360.));
Examples:
deg = -90
-> [0, 360)
:
deg -= 360. * std::floor(-90 / 360.);
deg -= 360. * -1;
deg = 270
deg = 270
-> [-180, 180)
:
deg -= 360. * std::floor((deg + 180.) / 360.);
deg -= 360. * std::floor(480. / 360.);
deg -= 360. * 1.;
deg = -90;
See: http://en.cppreference.com/w/cpp/numeric/math/floor
So if figured out a way to effectively do what i want using Mystical's approach to constraining the Angle. Here it is:
This seems to work with any example i can think of.
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)