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.

[cc lang=”swift”]

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

}

[/cc]

Source for the formula and picture:

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

## Leave a Reply