Search code examples
c++rangeangle

Clamp angle to arbitrary range


I need a function to clamp an angle (in degrees) into an arbitrary range [min,max]. Here are some examples: Angle range examples

The colored areas represent the valid angle range.

  • In image #1, ang should be clamped to max (-90)
  • In image #2, ang should be clamped to min (135)
  • In image #3, ang should be clamped to min (135)

This is what I have so far:

static float clamp_angle(float ang,float min,float max)
{
    ang = normalize_angle(ang); // normalize_angle transforms angle into [-180,180) range
    min = normalize_angle(min);
    max = normalize_angle(max);
    if(angle_in_range(ang,min,max) == false)
    {
        if(abs(get_angle_difference(ang,min)) < abs(get_angle_difference(ang,max))
            ang = min; // Clamp to min if we're closer to min than max
        else
            ang = max;
    }
    return ang;
}

What I'm missing is the function angle_in_range (true if the angle is within the range, otherwise false).
What would be the simplest way of determining whether the angle is within the range or not?


Solution

  • You can normalize angles in such a way that ang become 0 and min and max is mapped to [-180; 180). Then you can check if angle is in provided range like this:

    float clamp_angle(const float ang, const float min, const float max)
    {
        float n_min = normalize180(min-ang);
        float n_max = normalize180(max-ang);
    
        if (n_min <= 0 && n_max >= 0)
        {
            return ang;
        }
        if (abs(n_min) < abs(n_max))
            return min;
        return max;
    }
    

    Live On Coliru