Page 1 of 1

How can I smoothly lerp between two values?

Posted: Sun Dec 04, 2016 8:39 am
by jthistle
Hi,

I'm try to smoothly lerp between two coordinates with the formula:

Code: Select all

function lerp(a,b,t) return a * (1-t) + b * t end
However, this formula just makes the movement instant and with a constant velocity.

Does anyone know how I can get a smooth start and a smooth end, a bit like Unity's lerp function?

Thanks for any help!

Re: How can I smoothly lerp between two values?

Posted: Sun Dec 04, 2016 9:29 am
by Tjakka5
What you're looking for it tweening. (Probably a "Out-In-Quad")
I'd suggest using a library for that.

You can use either [url = https://github.com/rxi/flux]Flux[/url] or Hump timer.

Re: How can I smoothly lerp between two values?

Posted: Sun Dec 04, 2016 2:46 pm
by jthistle
Ah, flux works really well. Thanks very much!

Re: How can I smoothly lerp between two values?

Posted: Sun Dec 04, 2016 2:57 pm
by s-ol
jthistle wrote:Hi,

I'm try to smoothly lerp between two coordinates with the formula:

Code: Select all

function lerp(a,b,t) return a * (1-t) + b * t end
However, this formula just makes the movement instant and with a constant velocity.

Does anyone know how I can get a smooth start and a smooth end, a bit like Unity's lerp function?

Thanks for any help!
lerp is an abbreviation for linear interpolation. Linear interpolation always starts and stops instantly and moves, well... linearly, at constant speed.

Tjakka is right, you want some in-out easing function. There's many options of functions, but I would not say you need a library for it.

To get started: first learn quad-in interpolation. Basically you use your lerp function from above, but you take the t and preprocess it. t goes from 0 to 1, if you square it it still goes from 0 to 1, but it starts off slower than before:

Code: Select all

function quadin(a, b, t) return lerp(a, b, t * t) end
Now your interpolation ends on a really high spsed though, so really you want to apply quad for the first half, and then apply it in reverse for the second half of t. thats how quad-in-out works:

Code: Select all

function quad_in_out(a, b, t)
  if t <= 0.5 then
    return quadin(a, b, t*2) - (b-a)/2 -- scale by 2/0.5
  else
    return quadin(a, b, (1 - t)*2) + (b-a)/2 -- reverse and offset by 0.5
  end
end
This may not be the most intuitive code (and i might've made a mistake typing it from scratch here) but you should be able to figure it out.

For the first half, you multiply t by 2 to get it back onto the 0-1 scale for the first half, so the quadin function works as expected. Results are scaled in half so it stops early and the second half can continue from there.

Second half you need to reverse (1 - x) and then multiply times 2 so that at 0.5s you get a '1' and at 1s you get a '0' - you reversed and scaled the quadin function to fit the second half.

You might want to plot some of the functions involved in Wolfram alpha or something similar, that helps a lot.

Re: How can I smoothly lerp between two values?

Posted: Sun Dec 04, 2016 8:13 pm
by airstruck
I've been looking at something recently that might make a good non-piecewise alternative to the above. Have been using it for something else, but it might work here.

Code: Select all

y = 1.5 * x - 0.5 * x ^ 3
Try this out in wolfram alpha, it makes a nice smooth curve with y=0 when x=0, y=-1 when x=-1, and y=1 when x=1. The y axis peaks at 1 and has a valley at -1. I think instead of scaling to 0..1 first, you could scale to -1..1 and then apply this formula, and get an ease-in-out type thing without needing any if/then logic.

You can get something closer to a straight line (y = x) by reducing the 1.5 and 0.5 by the same amount. This makes the peak happen "late," so the easing in and easing out is less pronounced. For example:

Code: Select all

y = 1.2 * x - 0.2 * x ^ 3
Notice that y = 1.0 * x - 0.0 * x ^ 3 would reduce to y = x (linear).

You can also increase the 1.5 and 0.5 by the same amount (say 1.7 and 0.7) to get the peak early, so you have something like a "bounce" type of easing. Or you can apply the original formula 2 or 3 times or more to get more pronounced easing, with the peak and valley still at 1 and -1.

If you just want ease-in, you can scale to -1..0, and if you just want ease-out you can scale to 0..1.

Note that you can also formulate this in different ways, which might be cheaper. This should also work:

Code: Select all

y = x * (1.5 - 0.5 * x ^ 2)
I might not be doing a good job of explaining this because I haven't actually tried to apply this formula to easing, but maybe someone more experienced with this stuff can comment (pgimeno, are you reading this?).

Re: How can I smoothly lerp between two values?

Posted: Sun Dec 04, 2016 8:48 pm
by Jasoco
Flux is my favorite go-to for tweening. I've even added a few new tweens of my own that Flux doesn't have for "simplicity" reasons. Like a bounce tween or an alternative version of the backout tween.

Re: How can I smoothly lerp between two values?

Posted: Mon Dec 05, 2016 12:20 am
by pgimeno
I wrote a collection of blending functions for tweening here: https://www.love2d.org/forums/viewtopic ... 29#p198129

(with special emphasis on functions that ease the start and end, which I call sigmoids)

Re: How can I smoothly lerp between two values?

Posted: Tue Dec 06, 2016 5:23 pm
by Jimanzium
I believe this is what you want, change 0.5 for different speeds.

Code: Select all

function lerp(a,b,t) return a + (b-a) * 0.5 * t end