Skip to main content

Spline

A smooth curve that passes through the points you click, in order — for traced outlines, cam profiles and any free-form side where you know points on the curve. A bezier is shaped by handles that pull it; a spline goes exactly through its points.

In the viewport​

  1. Click Spline on the sketch toolbar.
  2. Click the points the curve should pass through, in order: the start, every point along the way, then the end. Each click adds one point to the statement, and the curve preview updates as you go.
  3. Esc ends the curve.

A point that snaps onto an existing vertex gets a coincident written for it. Once drawn, every point is a dot you can drag; the curve re-solves and redraws as it moves.

The code behind it
cam.part.js
import { sketch, spline, line } from 'fluidcad/core';
import { coincident, fix, horizontal, vertical, distance } from 'fluidcad/constraints';

sketch("xy", () => {
// A cam profile: the lobe is a spline THROUGH measured points — every
// point you pass is on the curve, unlike a bezier's control points.
const base = line([0, 0], [80, 0]);
const lobe = spline([80, 0], [85, 20], [60, 45], [25, 40], [0, 30]);
const side = line([0, 30], [0, 0]);
// Join the curve to the lines so the profile closes; the curve itself is
// not a solver entity, only its points are.
coincident(base.end(), lobe.start());
coincident(lobe.end(), side.start());
coincident(side.end(), base.start());
horizontal(base);
vertical(side);
fix(base.start(), [0, 0]);
distance(base.start(), base.end(), 80);
distance(side.start(), side.end(), 30);
// The measured points stay where they were read off the drawing.
fix(lobe.point(1), [85, 20]);
fix(lobe.point(2), [60, 45]);
fix(lobe.point(3), [25, 40]);
})

By hand​

spline(p0, p1, ..., pn)

The first point is the start and the last the end; the curve passes through every point between. The curve is a cubic interpolating B-spline, continuous in curvature, parameterized by chord length — moving one point reshapes it smoothly around that point. Two points draw a straight segment, three a quadratic curve.

A point can also be another entity's accessor (l.end()), in which case the curve rides that point. Two consecutive points at the same position are an error.

Accessors​

AccessorMeaning
s.point(i)The i-th point, 0-based — point(0) is the start
s.start()Same as point(0)
s.end()The last point
note

The curve itself is not a solver entity. Its points are: constrain s.point(i), s.start() and s.end() and the solve reshapes the curve. tangent, distance and the other entity-level constraints do not accept a spline.

The Mirror tool mirrors a spline point by point; Offset writes an offset() statement for a selection holding one; Trim and Split do not cut a spline, though it counts as a crossing for the edges it meets.