As I’m not really good at maths, figuring this out took me a while; I wanted some code to let an object follow a long smooth path. But googling for hours didn’t give my any usable results.

One way to solve this, is to take two points on the curve and use the normalized difference to have a vector that is aligned to the curve. But this is imprecise and I wanted to do this properly.

So I looked up a b-spline function that is defined by four points (a, b, c, d):

In code, I wrote this. Blend functions separated for optimization, because some languages do not support operator overloading:

// blend functions

b0 = it * it * it / 6

b1 = (3 * t * t * t - 6 * t * t + 4) / 6

b2 = (-3 * t * t * t + 3 * t * t + 3 * t + 1) / 6

b3 = t * t * t / 6

// calculate point

pointX = b0 * a.x + b1 * b.x + b2 * c.x + b3 * d.x

pointY = b0 * a.y + b1 * b.y + b2 * c.y + b3 * d.y

pointZ = b0 * a.z + b1 * b.z + b2 * c.z + b3 * d.z

And apparently, if we derive this (thank heavens for Wolfram|Alpha), we get the function that can be used to evaluate the velocity (or direction/tangent if normalized) at a certain point along the curve:

Which in code would look something like this:

// blend functions

b0 = it * it;

b1 = 1 + 2 * t - 3 * t * t

// calculate velocity

velocityX = (-(a.x * b0) + t * (-4 * b.x + 3 * b.x * t + d.x * t) + c.x * b1) / 2

velocityY = (-(a.y * b0) + t * (-4 * b.y + 3 * b.y * t + d.y * t) + c.y * b1) / 2

velocityZ = (-(a.z * b0) + t * (-4 * b.z + 3 * b.z * t + d.z * t) + c.z * b1) / 2

You can do this with any number of dimensions. And in C#, C++ or any other language that supports operator overloading, the above code could look much simpler.