SwiftUI Field Guide

Catmull–Rom Splines

Catmull-Rom splines offer a way to draw a smooth curve through a series of points. To be more precise, it can be seen as a series of connected cubic Bézier segments that pass exactly through each of the given key points.

For example, if we add points to the editor below, we will see a smooth curve that passes through each of them. One interesting effect is that adding a point to the drawing changes the curve segment before. We can also play around with the tension parameter to see the effect (in SwiftUI, this is not a value we can control, but it's interesting to play around with).

Drawing
Draw a Catmull–Rom spline through 0 pointsClick to add pointsClick to append a point and drag a point to move it. On the canvas, arrow keys move the placement cursor and Enter adds a point. On a point, arrow keys move it and Delete removes it. Shift moves in larger steps. Coordinates run from 0 to 100, with y increasing downward. Command or Control Z undoes the last edit.0 points in the drawing.
Tension
0

Values Over Time

The drawing above gives complete freedom to place points anywhere, and the resulting curve will smoothly pass through all of them. In SwiftUI's keyframe implementation, however, we can provide cubic keyframes with a specific duration. Multiple consecutive cubic keyframes are interpolated using Catmull-Rom. In the diagram below, each rounded rectangle represents a keyframe. The width is the duration and the value (in this case) is a simple scalar value. As we drag the values up and down and adjust the durations, we can see how the resulting curve changes accordingly.

Code
let timeline = KeyframeTimeline(    initialValue: 0.0) {    CubicKeyframe(-30, duration: 0.25)    CubicKeyframe(30, duration: 0.5)    CubicKeyframe(0, duration: 0.25)}
Curve
Editable value over time-30030Value00.51Time (s)

Drag points vertically to change values. Drag the lower handles to change timing. Arrow keys edit a selected point; hold Shift for larger steps. Delete removes an interior point.

4 points.

In SwiftUI's keyframe animations we're not limited to scalars but we can animate any type that conforms to Animatable. These are not as easy to visualize, but the principle is the same.

If we turn on the velocity diagram, we'll see how the velocity is continuous but not smooth. In other words, Catmull-Rom splines are C1 continuous.

Resources

Share Image

In our Cubic Bézier Keyframes series on Swift Talk, we build up from Bézier curves to Catmull–Rom interpolation between cubic keyframes. Watch part 1 (#369), part 2 (#370), part 3 (#371), part 4 (#372), and part 5 (#373).

https://talk.objc.io/episodes/S01E373-cubic-bezier-keyframes-part-5
Share Image

Freya Holmér's video The Continuity of Splines.

https://www.youtube.com/watch?v=jvPPXbo87ds
Share Image

Bartosz Ciechanowski's interactive article Curves and Surfaces.

https://ciechanow.ski/curves-and-surfaces/