Normalise orientation between 0 and 360

Viewed 63766

I'm working on a simple rotate routine which normalizes an objects rotation between 0 and 360 degrees. My C# code seems to be working but I'm not entirely happy with it. Can anyone improve on the code below making it a bit more robust?

public void Rotate(int degrees)
    {
        this.orientation += degrees;

        if (this.orientation < 0)
        {
            while (this.orientation < 0)
            {
                this.orientation += 360;
            }
        }
        else if (this.orientation >= 360)
        {
            while (this.orientation >= 360)
            {
                this.orientation -= 360;
            }
        }
    }
10 Answers

This is one that normalizes to any range. Useful for normalizing between [-180,180], [0,180] or [0,360].

( it's in C++ though )

// Normalizes any number to an arbitrary range 
// by assuming the range wraps around when going below min or above max 
double normalize( const double value, const double start, const double end ) 
{
  const double width       = end - start   ;   // 
  const double offsetValue = value - start ;   // value relative to 0

  return ( offsetValue - ( floor( offsetValue / width ) * width ) ) + start ;
  // + start to reset back to start of original range
}

For ints

// Normalizes any number to an arbitrary range 
// by assuming the range wraps around when going below min or above max 
int normalize( const int value, const int start, const int end ) 
{
  const int width       = end - start   ;   // 
  const int offsetValue = value - start ;   // value relative to 0

  return ( offsetValue - ( ( offsetValue / width ) * width ) ) + start ;
  // + start to reset back to start of original range
}

So basically the same but without the floor. The version I personally use is a generic one that works for all numeric types and it also uses a redefined floor that does nothing in case of integral types.

I'd recommend making separate function for normalizing angle - it's a cleaner solution.

public static float NormalizeEulerAngle(float angle){
    var normalized = angle % 360;
    if(normalized < 0)
        normalized += 360;
    return normalized;
}

Fiddle proving that such function works as intended: https://dotnetfiddle.net/Vh4CUa

And then you can use it like here:

public void Rotate(int degrees){
    orientation = NormalizeEulerAngle(orientation + degrees);
}

A bit late to the party, but it would seem many of the preferred solutions make an assumption that a negative angle will not be lower than -360°. This solution makes no such assumption, works for virtually any angle that an int can represent, and does not do excessive multiplication or division:

public void Rotate(int degrees)
{
    this.orientation += degrees;
    
    if (this.orientation >= 0)
        this.orientation %= 360;
    else
        this.orientation = 360 - (360 - this.orientation) % 360;
}

Function that comes handy when normalizing angles (degrees) into interval [0, 360> :

float normalize_angle(float angle)
{
    float k = angle;

    while(k < 0.0)
        k += 360.0;
    while(k >= 360.0)
        k -= 360.0;
    return k;
}
Related