Deriving the best interpolation function

I wanted to play around with a simple VR app with fun affects around the hand detections from the Quest 3 headset.

I had plans for all kinds of effects I wanted to do, and I started with this simple sphere following my finger. But it didn’t look nice enough at first!

So I became interested in deriving a smoothstep function by myself.

Nice interpolation of sphere position

Detour - deriving smoothstep ourselves

Idea - smoothness at the edges, constant speed inbetween. Because what if we want to travel large distances

Idea for the interpolation function with a straight section

Constraints:

  • f(0)=0f(0)=0
  • f′(0)=0f'(0) = 0
  • D=f(p)+f′(p)∗(T−2p)+f(p)D = f(p) + f'(p) * (T - 2p) + f(p)
  • Where 0≤D,0≤T,0≤p≤T/20 \leq D, 0\leq T, 0\leq p \leq T/2
  • Given DD, TT, and PP as input constraints, we then have 1 less degree of freedom for whatever parameters define f(x)f(x)
  • Controlling for a, we get a set of curves, which all satisfy our needs
  • Another thing: f′′(p)≥0f''(p) \geq 0, so that our function on “warmup” is always curved in

Using a cubic function:

{f(x)=ax3+bx2+cx+df(0)=0f′(0)=0f′′(p)≥0D=2f(p)+f′(p)∗(T−2p)⟹{f(x)=ax3+bx2b=D+4ap3−3ap2T2pT−2p2a≥−D3p2T−2p3\begin{cases} f(x) = ax^3 + bx^2 + cx + d \\ f(0) = 0 \\ f'(0) = 0 \\ f''(p) \geq 0 \\ D = 2f(p) + f'(p) * (T - 2p) \end{cases} \Longrightarrow \begin{cases} f(x) = ax^3 + bx^2 \\ b = \frac{ D + 4ap^3 -3ap^2T}{2pT-2p^2 } \\ a \geq -\frac{D}{3p^2T - 2p^3} \end{cases}

The function is nice! Desmos here: https://www.desmos.com/calculator/rlfikf4yzl

seam carving comparison
Nice interpolation of sphere position

Also as a fun side-thing I just made a desmos visual of all functions from Inigo Quilez’s post on smoothstep functions : https://www.desmos.com/calculator/uo1b8hmmgy

But then I’ve got a problem - this function is complicated to compute the inverse of, which I’ll need later. There are formulas for computing the inverse for the cubic from above, and Inigo Quilez even did a post about it. But I don’t want to integrate it because it’s not something I want to derive right now

So I tried a couple more families of functions:

  • b(1−cos⁡(ax))b(1 - \cos(ax))
  • axbax^b

This is all fun & stuff, but the section is called a detour because this function specification isn’t very useful. The speed of the middle section is derived, not an input parameter. and the “warmup distance” isn’t an input parameter.

Deriving a “warmup/warmdown” function

The purpose is to get a function with specific warmup / warmdown properties. I.e.:

  • The warmup/warmdown must take time TT
  • During the warmup/warmdown, distance DD should be traveled
  • By the end of warmup we should have speed VV

Or:

{f(0)=0f′(0)=0f(T)=Df′(T)=Vf′′(x)≥0,0≤x≤T\begin{cases} f(0) = 0 \\ f'(0) = 0 \\ f(T) = D \\ f'(T) = V \\ f''(x) \geq 0,& 0\leq x\leq T \end{cases}

Didn’t manage to derive this for a cubic ax3+bx2ax^3 + bx^2 or a trigonometrical b(1−cos⁡(ax))b(1 - \cos(ax))

But it was very doable for axbax^b !

b=TVD,  a=DTbb=\frac{TV}{D}, \; a=\frac{D}{T^b}

Here’s the Desmos: https://www.desmos.com/calculator/liqymuycjg

New warmup function

Assume current position is xx , target position is tt, and current speed is ss

d=∣∣x−t∣∣d = ||x-t|| – the distance to target

  • If d≥Dd \geq D:

    • if v=Vv = V , then we’re up to speed and don’t need to do anything, just update position

    • i.e. we’re not close enough to do “warmdown” yet, we should do “warmup”:

      xnew≔x+vΔtvnew≔f′(f′−1(v)+Δt)\begin{equation} \begin{aligned} x_{\text{new}} \coloneqq & x + v \Delta t \\ v_{\text{new}} \coloneqq & f'(f'^{-1}(v) + \Delta t) \end{aligned} \end{equation}
  • Otherwise we need to do “warmdown”, strictly according to the function:

    xnew≔f(f−1(d)−Δt)vnew≔f′(f−1(d)−Δt)\begin{equation} \begin{aligned} x_{\text{new}} \coloneqq & f(f^{-1}(d) - \Delta t) \\ v_{\text{new}} \coloneqq & f'(f^{-1}(d) - \Delta t) \end{aligned} \end{equation}

Voila! It works