Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotation Interpolation

NB: I'll present this question in degrees purely for simplicity, radians, degrees, different zero-bearing, the problem is essentially the same.

Does anyone have any ideas on the code behind rotational interpolation? Given a linear interpolation function: Lerp(from, to, amount), where amount is 0...1 which returns a value between from and to, by amount. How could I apply this same function to a rotational interpolation between 0 and 360 degrees? Given that degrees should not be returned outside 0 and 360.

Given this unit circle for degrees:

Unit Circle

where from = 45 and to = 315, the algorithm should take the shortest path to the angle, i.e. it should go through zero, to 360 and then to 315 - and not all the way round 90, 180, 270 to 315.

Is there a nice way to achieve this? Or is it going to just be a horrid mess of if() blocks? Am I missing some well understood standard way of doing this? Any help would be appreciated.

like image 264
Rob Avatar asked Apr 25 '10 14:04

Rob


People also ask

How do you interpolate between angles?

Between two anglesIf θ0−π≤θ1≤θ0 then interpolation is θ0+r(θ1−θ0). If θ0+π≤θ1≤θ0+2π then interpolation is θ0+r(θ1−θ0−2π). If θ0−2π≤θ1≤θ0−π then interpolation is θ0+r(θ1−θ0+2π).

What is the interpolation method?

Interpolation is a statistical method by which related known values are used to estimate an unknown price or potential yield of a security. Interpolation is achieved by using other established values that are located in sequence with the unknown value. Interpolation is at root a simple mathematical concept.

What is an example of interpolation?

Based on the given set of data, farmers can estimate the height of trees for any number of days until the tree reaches its normal height. Based on the above data, the farmer wants to know the height of the tree on the 7th day. He can find it out by interpolating the above values.


3 Answers

I know this is 2 years old, but I've recently been looking around for the same problem and I don't see an elegant solution without ifs posted in here, so here it goes:

    shortest_angle=((((end - start) % 360) + 540) % 360) - 180;     return shortest_angle * amount; 

that's it

ps: of course, % is meaning modulo and shortest_angle is the variable that holds the whole interpolation angle

like image 157
user151496 Avatar answered Sep 21 '22 15:09

user151496


Sorry, that was a bit convoluted, here's a more concise version:

    public static float LerpDegrees(float start, float end, float amount)     {         float difference = Math.Abs(end - start);         if (difference > 180)         {             // We need to add on to one of the values.             if (end > start)             {                 // We'll add it on to start...                 start += 360;             }             else             {                 // Add it on to end.                 end += 360;             }         }          // Interpolate it.         float value = (start + ((end - start) * amount));          // Wrap it..         float rangeZero = 360;          if (value >= 0 && value <= 360)             return value;          return (value % rangeZero);     } 

Anyone got a more optimised version?

like image 22
Rob Avatar answered Sep 20 '22 15:09

Rob


I think a better approach is to interpolate sin and cos since they don't suffer form being multiply defined. Let w = "amount" so that w = 0 is angle A and w = 1 is angle B. Then

CS = (1-w)*cos(A) + w*cos(B);
SN = (1-w)*sin(A) + w*sin(B);
C = atan2(SN,CS);

One has to convert to radians and degrees as needed. One also has to adjust the branch. For atan2 C comes back in the range -pi to pi. If you want 0 to 2pi then just add pi to C.

like image 20
Paul Colby Avatar answered Sep 22 '22 15:09

Paul Colby