|

Curves

Curve constructions over a list of knots. Each takes points and returns a dense polyline through them. They pair with resampleEvery: pick knots from a drawn path at a fixed span, then connect them with one of these, and the wobble of the hand disappears between the knots.

public/lib/curves.js

resampleEvery

Points spaced span apart along the polyline, walked by arc length. The first and last points are always kept, so the curve starts and ends where the path did. A span of zero returns every point unchanged.

naturalSpline

A natural cubic spline through the knots: C2 continuous, with zero second derivative at the ends. Parameterized by chord length, so uneven knot spacing does not distort the shape. Takes samplesPerSegment.

catmullRomSpline

A centripetal Catmull-Rom spline through the knots, evaluated segment by segment. Each segment depends only on its four surrounding knots, so appending a knot changes the last two segments and nothing before them: a growing path keeps its settled shape exactly. The cost is C1 continuity instead of C2. Takes samplesPerSegment and closed; when closed, the neighbors wrap and the joining segment is built like every other, so the loop closes smoothly.

bSpline

A uniform cubic B-spline over the knots, with the ends clamped by repetition. Each span depends on four consecutive knots, so like the Catmull-Rom it cannot move the settled part of a growing path. It is C2 continuous, and pays for it by approximating the knots instead of passing through them. Takes samplesPerSegment and closed; when closed, the spans wrap instead of clamping and the loop closes with C2 continuity.

hobbyCurve

John Hobby’s curve through the knots, the interpolation METAFONT draws paths with. Tangent directions come from a mock-curvature linear system solved with the Thomas algorithm, and control handles from Hobby’s velocity function. Adapted from Jake Low’s implementation (ISC license). Takes samplesPerSegment and omega, the curl at the endpoints.

It swings wider through corners than the natural spline. The natural spline minimizes bending energy along the whole curve, while Hobby’s construction aims for locally even curvature, which rounds a corner into a fuller arc.

splitByTurn

Splits a point list into separate runs wherever the direction turns more than angle radians. The turn at a point compares the incoming and outgoing directions, each measured over span of arc rather than one segment, so the jitter of dense points does not trigger cuts. A cut cannot follow another within span of arc, so one corner yields one cut, and each run shares its boundary point with the next, so the pieces stay connected end to end.

hasSettledStart

Whether a growing gesture carries enough arc for a stable direction. Walks the points and passes once the accumulated arc reaches minArc; a mark held until then appears already settled, instead of flickering through the tangent swings of the first few samples. Distance rather than a point count, since a slow hand piles points onto one spot without adding direction.

smoothByWidth

Smoothing that follows the stroke’s width: the knot spacing is width × gain, clamped to [minSpan, maxSpan], interpolated with the local Catmull-Rom so the settled part of a growing stroke holds still. A narrow stroke follows the hand directly; a wide one rounds its turns before they can fold the geometry over itself.