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