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:
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.
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π).
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.
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.
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
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With