- Joined
- Jul 31, 2017
- Messages
- 500
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: