2010-06-29

# Unwrapping Values – nearest next angle from a previous angle

So, assuming you have angles previousAngle and nextAngle, and you want to transition from the first to the second smoothly. If it’s like from 358 to 2, a simple linear interpolation will awfully go through almost a full circle down from 358 to 2, when a simple four degree transition forward would have been enough, i.e. you should have been going to 362 degrees instead. So, how to figure out what’s the shortest transition?

I remember hitting against this problem numerous times, always remembering that I have solved it previously but always seem unable to find the previous solution. And I still can’t just write it out by heart.

Once again I had to solve this, so this time I tried to Google for it (“angle wrap delta”), and found out that somebody named Jason S had posted a nice generalization to a related question in Stackoverflow.com.

For your convenience, I’m posting a modified C version of the code here.

``` // Fancy generalization for wrapping below (e.g. for angles). // Original code found from: // http://stackoverflow.com/questions/2500430/calculating-rotation-in-360-deg-situations```

``` // symmetric modulo: // y = smod(x,m) = x+k*m where k is an integer, // and y is always in the range [-0.5,0.5)*m static float smod(float x, float m) {   return x - ((floorf(x / m + 0.5f)) * m); } ```

```// Unwraps a value, used for e.g. angles. // Caveat: Doesn't handle negative input values correctly. // Workaround: Wrap original value prev to [0..range) before applying this. //       e.g.: prev = fmodf(fmodf(prev, range) + range, range); static float unwrap(float prev, float next, float range) {   return prev + smod(next - prev, range); } ```

There’s one caveat: it doesn’t seem to work correctly for negative angles. Just now I don’t have the time now to figure that out. But an easy workaround is to wrap the original angle first with angle=fmodf(fmodf(angle,2*pi)+2*pi,2*pi) and then transition from that angle to the destination. If somebody posts a better version I’ll update the post. :)

### One response:

1. jetro says:

Edit: Fixed the suggested workaround to correctly contain +range (or +2*pi) after the first fmodf.