2
function lerp(start, end, amt) {
    return (1-amt)*start+amt*end
}

This lerp function works perfectly with coords. I can easily lerp X from 1 to 10.
But problems appear when it comes to rotation. The rotation of an object is in radians. It can be from -3.14 to 3.14. So let's rotate our object. Starting from 0, one moment the rotation will reach to 3.14, and then... -3.14. So when lerping from 3.14 to -3.14, the object makes one full 360ΒΊ rotation, (3.14, 2, 1, 0, -1, -2, -3.14) which is not good. So, can anybody tell, how to lerp the rotation?
I am using JavaScript.

AnimateMe
  • 57
  • 7

2 Answers2

6

Honestly, I don't remember how this works. But, it works.

Its in my code to deal with lerping rotation of a player object to point towards the mouse, when the pointer angle traverses -3.14 to 3.14 this function correctly calculates the lerp across the gap. With, um, magic.

function rLerp (A, B, w){
    let CS = (1-w)*Math.cos(A) + w*Math.cos(B);
    let SN = (1-w)*Math.sin(A) + w*Math.sin(B);
    return Math.atan2(SN,CS);
}
Colin Smith
  • 300
  • 2
  • 8
  • 2
    I wanted to add more information for anyone coming back to this. I sort of wanted to understand why/how this works, and, I find it pretty clever for whoever initially came up with this. Effectively, A (the source angle) and B (the goal angle) are converted to an X/Y offset using cos/sin in the same way you might turn an angle into a unit vector. Then, instead of lerping the angle directly, this unit vector is lerped, and converted back into an angle using atan2. E.g. for SN, it is effectively `xOffsetAfterLerp = lerp(sin(angleFrom), sin(angleTo), alpha)` and CS is the yOffset (cos). – Hexcede Oct 23 '22 at 04:09
  • I love you. just spent sooooo long trying to make this work. – Jonathan Plackett Dec 08 '22 at 20:23
  • what is the "w" argument? – CalAlt Feb 21 '23 at 10:23
-1

If end value is less than start one, increment it by 2*Pi, and make interpolation.

Map intermediate values into needed range.

Python code (JS one is close)

a0 = 3
a1 = - 3
if a1 < a0:
    a1 += 2*math.pi
for i in range(11):
    a = a0 * (1 - i/10) + a1 * i / 10
    if a > math.pi:
        a -= 2*math.pi
    print(a)

3.0
3.028318530717959
3.0566370614359175
3.0849555921538756
3.113274122871834
3.141592653589793
-3.113274122871834
-3.084955592153876
-3.056637061435917
-3.028318530717959
-3.0
MBo
  • 77,366
  • 5
  • 53
  • 86