Fastest way to interpolate between radians?

1.5k views Asked by At

So, I have radian angles without any range (-inf to +inf basically) and I need to interpolate these as quick as possible. If there any cookie cutter way to do this?

PS: I only need to interpolate 2 values at a time, so a+f*(b-a) basically

PPS: the output does NOT have to be in any specific range (-PI to PI or 0 to 2PI)

PPPS: The specific problem is how to do the wrapping of the values around -PI/+PI and their multiples most efficiently

2

There are 2 answers

4
Danvil On BEST ANSWER

BETTER Actually forget what I wrote first. You can simply do:

template<typename K>
K lerpAngle(K u, K v, K p) {
    return u + p*wrapMP(v - u);
}

where wrapMP moves an angle to the interval [-pi|+pi]. Both input u and v can be any radian angle and the result will also not be in a specific interval.

The idea is actually quite simple. Move your point of view to the point u such that u=0. Now v can be arbitrary as angles are not normalized, but we just wrap the distance v-u = v to [-pi|+pi] and walk by the given percentage p into that direction.


OLD (and inefficient) I wrote this code once:

template<typename K>
K lerpAngle(K u, K v, K p) {
    K a = wrap2Pi(u);
    K b = wrap2Pi(v);
    K d = b - a;
    if(d < -PI) {
        b += 2*PI;
    }
    if(d > +PI) {
        b -= 2*PI;
    }
    return wrap2Pi(a + p*(b - a));
}

where wrap2i moves an angle to the interval [0,2*pi[.

2
leemes On

First, "normalize" your input angles so they're in a specific range, like (-π, π]. If you do this already, skip this part.

Then, take their difference. If the absolute value of this difference is greater than π then adjust one of the inputs by adding / subtracting such that the absolute value of the difference becomes less or equal to π.

Then simply interpolate between those two values.

If the output of this interpolation should always be in the range (-π, π] again (note: it probably doesn't have to, depending on where you need this angle), then add / subtract again if it's not.