Just so that the next person can avoid having to do the wikipedia-math-formula-to-Swift conversion, here’s a simple Catmull-Rom interpolation method for linear y=x data. I’m using it to create simple ski jump hill profiles for a possibly upcoming game, it’s so easy to describe a hill profile by just giving it control points and let the interpolator do the math. This will work just fine for any time-based keyframe data, too.

Notes: you need to give 4 **different** points of data – if you give duplicates, the formula will turn the return value into a NaN for obvious reasons.

I’m using a simple 2d point data to feed the thing.

class Point {

var x : Float = 0.0

var y : Float = 0.0

}

// t: relative position between p1 and p2, in 0 .. 1 range

// i left it as a relative value so that this can easily

// be turned into a general-purpose 2d curve interpolator

// p0, p1, p2, p3: the four points

func CatmullRom(t: Float, _ p0: Point, _ p1: Point, _ p2: Point, _ p3: Point) -> Float

{

let alpha : Float = 0.5

let t0 : Float = 0.0

let t1 = t0 + alpha * (sqrtf(powf(p1.x - p0.x, 2.0) + powf(p1.y - p0.y, 2.0)))

let t2 = t1 + alpha * (sqrtf(powf(p2.x - p1.x, 2.0) + powf(p2.y - p1.y, 2.0)))

let t3 = t2 + alpha * (sqrtf(powf(p3.x - p2.x, 2.0) + powf(p3.y - p2.y, 2.0)))

let tt = t * (t2 - t1) + t1

let a1 = (t1 - tt) / (t1 - t0) * p0.y + (tt - t0) / (t1 - t0) * p1.y

let a2 = (t2 - tt) / (t2 - t1) * p1.y + (tt - t1) / (t2 - t1) * p2.y

let a3 = (t3 - tt) / (t3 - t2) * p2.y + (tt - t2) / (t3 - t2) * p3.y

let b1 = (t2 - tt) / (t2 - t0) * a1 + (tt - t0) / (t2 - t0) * a2

let b2 = (t3 - tt) / (t3 - t1) * a2 + (tt - t1) / (t3 - t1) * a3

let c = (t2 - tt) / (t2 - t1) * b1 + (tt - t1) / (t2 - t1 ) * b2

return c

}

Source for the formula and picture:

https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline

*Related*

Is there any chance you have this in 3D? I was having a hard time implementing it in 3D, since I’m still in school I don’t really understand this level of math yet, although I’ve recently started trying to learn it.

Thanks!

– Rohith

This example shows how to turn four points into a parametric 2d curve between points p1 and p2 – to do the same in 3D, you would probably need to do the math in at least two parameter pairs (x/y and x/z) or even better, do it three times and have the whole thing be parametric as described in this stackexchange post. I might try that and post it one day.

Hey!

Just wanted to let you know I was able to do it in Unity and it ended up being quite easy! Thanks for the reference.

Glad to hear that!