Skip to content

Instantly share code, notes, and snippets.

@scurest
Created March 5, 2020 13:53
Show Gist options
  • Save scurest/5ca8d1cedb27894d8a9b140c2630b6e6 to your computer and use it in GitHub Desktop.
Save scurest/5ca8d1cedb27894d8a9b140c2630b6e6 to your computer and use it in GitHub Desktop.
Sympy derivation of conversion from glTF to Blender bezier curve
from sympy import *
# glTF equation taken from Appendix C of the spec
# When time = t_cur, the value of the curve is p
v_k, v_kp1, t_k, t_kp1, b_k, a_kp1, t_cur = symbols('v_k v_kp1 t_k t_kp1 b_k a_kp1 t_cur')
t = (t_cur - t_k) / (t_kp1 - t_k)
p0 = v_k
m0 = (t_kp1 - t_k) * b_k
p1 = v_kp1
m1 = (t_kp1 - t_k) * a_kp1
p = (
(2 * t**3 - 3 * t**2 + 1) * p0 +
(t**3 - 2 * t**2 + t) * m0 +
(-2 * t**3 + 3 * t**2) * p1 +
(t**3 - t**2) * m1
)
# Blender equation
s = symbols('s')
# Formula for the x component
w0_x = t_k
w1_x = (2 * t_k + t_kp1) / 3
w2_x = (t_k + 2 * t_kp1) / 3
w3_x = t_kp1
x = (
(1 - s)**3 * w0_x +
3 * (1 - s)**2 * s * w1_x +
3 * (1 - s) * s**2 * w2_x +
s**3 * w3_x
)
# Formula for the y component
w0_y = v_k
w1_y = (3 * v_k + m0) / 3
w2_y = (3 * v_kp1 - m1) / 3
w3_y = v_kp1
y = (
(1 - s)**3 * w0_y +
3 * (1 - s)**2 * s * w1_y +
3 * (1 - s) * s**2 * w2_y +
s**3 * w3_y
)
# When s = t, then x = t_cur and y = p
assert simplify((x - t_cur).subs({s: t})) == 0
assert simplify((y - p).subs({s: t})) == 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment