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

Copy Markdown View Source

A cardinal spline: a Catmull-Rom spline with a :tension option that sets how tightly the curve bends at each knot.

You only give the knots, and the curve passes through every one of them. At each knot the curve heads in the direction from the knot before it to the knot after it. :tension sets how fast:

:tensionThe curve...
0.0 (the default)is exactly a Curves.Spline.Type.CatmullRom spline
between 0.0 and 1.0bends more tightly at each knot, with straighter lines between them
1.0stops at every knot: straight lines that slow down at each knot
below 0.0swings wider around each knot

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

curve = Curves.define_cardinal([{0, 0}, {2, 3}, {4, 1}, {6, 4}, {8, 2}], tension: 0.5)

# 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, "cardinal.svg")

Cardinal spline with tension 0.5

How it is built

The tangent at each knot is (1 - tension) * (next_knot - previous_knot) / 2. The first and last knots have no knot on one side, so the curve leaves the start heading straight for the second knot, and arrives at the end from the second-to-last one (the same as Catmull-Rom). Each segment is then the Hermite segment between two knots, stored as a cubic Bezier curve.