# Cubic Bézier Easing

#### Holzchopf

##### Moderator
3rd Party Module Dev
Tutorial Author
I stumbled across this article and thought it might come in handy to have a cubic-bezier function. And here it is:

Code:
``````' Cubic Bézier interpolation for easing curves
' pA ... pD are Bézier curve points
' pX the value for which the corresponding curve Y value shall be found
' pPrecision defines up to which error in Y the result shall be
' Returns: curve Y value at pX
Function CubicBezierEase:Float(pA:Float, pB:Float, pC:Float, pD:Float, pX:Float, pPrecision:Float = 0.0001)
' boundary conditions
If pX <= 0 Then Return 0
If pX >= 1 Then Return 1
' polynomial factors, precalculated for performance
Local pQuadr:Float = 3*pC - 6*pA
Local pCubic:Float = 1 + 3*pA - 3*pC
' A cubic bezier spline is a vector function
' (x, y) = f(t)
' The algorithm finds t for a given x
' iteratively
' and returns the corresponding y value.
' start at t = pX
Local t:Float = pX
' old value of t, step of t, how much t actually changed and next best guess for t
Local oldt:Float, tstep:Float, dt:Float, dttarget:Float
' value of x, old value of x and how much x actually changed in last iteration
Local x:Float, oldx:Float, dx:Float
' first iteration is special (in respect to calculation of tstep)
Local firstrun:Int = True
' iterate
Repeat
' calculate x of cubic bezier spline
x = 3*pA*t + pQuadr * t*t + pCubic * t*t*t
' accurately found t?
If Abs(x - pX) <= pPrecision Then
Exit
' no, move t
Else
' update tstep
' in first iteration
If firstrun then
firstrun = False
' tstep by how much x differs from target x
tstep = pX - x
' after that
Else
' adapt tstep by how much the value over- or undershoot
dx = x - oldx
dt = t - oldt
dttarget = (pX - oldx) / dx * dt
tstep = -dt + dttarget
Endif
' update t and clamp
oldt = t
t += tstep
If t > 1 then t=1
If t < 0 then t=0
EndIf
oldx = x
Forever
' calculate y of cubic bezier spline and return
Return 3*pB*t + (3*pD - 6*pB) * t*t + (1 + 3*pB - 3*pD) * t*t*t
End Function``````

Last edited:

#### Holzchopf

##### Moderator
3rd Party Module Dev
Tutorial Author
I updated the function. It now takes two more values: pY0 and pY1 which describe the start and end Y value. With this it's also possible to make curves that "pulse" or "fade out".

Code:
``````' Cubic Bézier interpolation for easing curves
' (Imagine a curve on the X-Y plane. Returns curve value at pX)
' pY0 and pY1 are curve Y values at X=0 and X=1 respectively
' pA ... pD are Bézier curve points
' pX the value for which the corresponding curve Y value shall be found
' pPrecision defines up to which error in Y the result shall be
' Returns: curve Y value at pX
Function CubicBezierEase:Float(pY0:Float, pY1:Float, pA:Float, pB:Float, pC:Float, pD:Float, pX:Float, pPrecision:Float = 0.0001)
' boundary conditions
If pX <= 0 Then Return pY0
If pX >= 1 Then Return pY1
' polynomial factors, precalculated for performance
Local pLin:Float = 3*pA
Local pQuadr:Float = 3*pC - 6*pA
Local pCubic:Float = 1 + 3*pA - 3*pC
' A cubic bezier spline is a vector function
' (x, y) = f(t)
' The algorithm finds t for a given x
' iteratively
' and returns the corresponding y value.
' start at t = pX
Local t:Float = pX
' old value of t, step of t, how much t actually changed and next best guess for t
Local oldt:Float, tstep:Float, dt:Float, dttarget:Float
' value of x, old value of x and how much x actually changed in last iteration
Local x:Float, oldx:Float, dx:Float
' first iteration is special (in respect to calculation of tstep)
Local firstrun:Int = True
' iterate
Repeat
' calculate x of cubic bezier spline
x = pLin * t + pQuadr * t*t + pCubic * t*t*t
' accurately found t?
If Abs(x - pX) <= pPrecision Then
Exit
' no, move t
Else
' update tstep
' in first iteration
If firstrun then
firstrun = False
' tstep by how much x differs from target x
tstep = pX - x
' after that
Else
' adapt tstep by how much the value over- or undershoot
dx = x - oldx
dt = t - oldt
dttarget = (pX - oldx) / dx * dt
tstep = -dt + dttarget
Endif
' update t and clamp
oldt = t
t += tstep
If t > 1 then t=1
If t < 0 then t=0
EndIf
oldx = x
Forever
' calculate y of cubic bezier spline and return
Return pY0 + (3*pB - 3*pY0) * t + (3*pY0 - 6*pB + 3*pD) * t*t + (pY1 + 3*pB - 3*pD - pY0) * t*t*t
End``````

You may be wondering why I didn't add those as optional parameters? Because I tried it and - believe me - it looked horrible with those two essential values attached at the back. For me, it makes much more sense to have this order: Interpolate from, to, via, at point X

##### New member
CX Code Contributor
3rd Party Module Dev
Nice! There is a lot of cool stuff in the material design guide.
That reminds me that I have some easing functions lying around since a long time. Maybe I should post them.