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:

enter image description here

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)

Tags:

C++

Math