How can I smoothly lerp between two values?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
jthistle
Prole
Posts: 5
Joined: Mon Sep 05, 2016 7:47 pm

How can I smoothly lerp between two values?

Post 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!
User avatar
Tjakka5
Party member
Posts: 243
Joined: Thu Dec 26, 2013 12:17 pm

Re: How can I smoothly lerp between two values?

Post 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.
User avatar
jthistle
Prole
Posts: 5
Joined: Mon Sep 05, 2016 7:47 pm

Re: How can I smoothly lerp between two values?

Post by jthistle »

Ah, flux works really well. Thanks very much!
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: How can I smoothly lerp between two values?

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: How can I smoothly lerp between two values?

Post 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?).
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: How can I smoothly lerp between two values?

Post 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.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: How can I smoothly lerp between two values?

Post 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)
User avatar
Jimanzium
Party member
Posts: 103
Joined: Sun Jun 03, 2012 2:39 pm
Contact:

Re: How can I smoothly lerp between two values?

Post 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
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests