Curves.Spline.Type.CentripetalCatmullRom (curves v1.0.1)

Copy Markdown View Source

A centripetal Catmull-Rom spline: like Curves.Spline.Type.CatmullRom, but it takes the distances between the knots into account, so it never makes little loops or sharp points (cusps), even when some knots are much closer together than others.

You only give the knots, and the curve passes through every one of them. The :alpha option, between 0.0 and 1.0, sets how much the distances count:

:alphaNameThe curve...
0.0uniformis exactly a Curves.Spline.Type.CatmullRom spline
0.5 (the default)centripetalnever loops or makes cusps within a segment
1.0chordalbends even more gently near knots that are far apart

A spline with n knots has n - 1 segments, like Catmull-Rom.

# Two knots close together between two far away: plain Catmull-Rom makes a little loop here.
curve = Curves.define_centripetal_catmull_rom([{0, 0}, {10, 10}, {10.5, 10}, {20, 0}])

# Find any point along the curve (u goes from 0.0 to Curves.max_u(curve))...
Curves.solve!(curve, 1.5)

# ...or draw the whole curve as an SVG image
Curves.Svg.save!(curve, "centripetal_catmull_rom.svg")
Plain Catmull-RomCentripetal
Catmull-Rom makes a loopCentripetal makes no loop

How it is built

Each segment, from knot p1 to knot p2, looks at the knots either side, p0 and p3. With d01, d12 and d23 for the distances between them, each raised to the power alpha:

leaving p1  = p2 - p1 + d12 * ((p1 - p0) / d01 - (p2 - p0) / (d01 + d12))
arriving p2 = p2 - p1 + d12 * ((p3 - p2) / d23 - (p3 - p1) / (d12 + d23))

Each segment is the Hermite segment with those tangents, stored as a cubic Bezier curve, and u still adds one per segment. A knot's tangent can be longer on one side than the other, so the speed along the curve can jump at a knot, but its direction never does.

The first and last knots have no knot on one side, so they get a made-up one, mirrored through the end (the same as Catmull-Rom). Two knots in the same place make a segment that stays on that point; a knot's neighbour in the same place is treated like the end of the curve.