Skip to content

Scientific geometry

Ribbons and tubes ​

scenes/ribbons-and-tubes
const paths = spirals(40, 120);
if (as === "tubes") {
  plot.showTubes(plot.uploadTubes(paths, 0.05, [0.9, 0.5, 0.2]));
} else {
  plot.showRibbons(plot.uploadRibbons(paths, 0.22, [0.3, 0.7, 0.9]));
}
plot.frameScene();

Calls

5 in the code above, in the order it makes them

plot.showTubes(handle: TubesHandle): void

Draw the tubes handle names.

plot.uploadTubes(paths: Paths, radius: number, colour: Colour | Hex): TubesHandle

Upload a set of curves swept into tubes, and return a handle naming them.

A polyline is one pixel wide however close the camera gets, which is fine for a gridline and wrong for a thing. A traced field line or a trajectory has extent, and a reader tells near from far by how they overlap.

radius is in world units, and a per-point widths column overrides it. The colour is given here rather than when it is drawn, because the sweep that builds the mesh bakes it in, and it is ignored where the curves carry a scalar per point.

plot.showRibbons(handle: RibbonsHandle): void

Draw the ribbons handle names.

plot.uploadRibbons(paths: Paths, width: number, colour: Colour | Hex): RibbonsHandle

Upload a set of curves swept into flat ribbons, and return a handle naming them.

The columns are a tube's, and width is the full width rather than a half-width. A ribbon is flat, so unlike a tube it carries an orientation: how it turns along its length is a second channel, which is what a curve with a frame attached has to show.

plot.frameScene(): void

Point the camera at the middle of everything uploaded, far enough back to see it.

Call after uploading. A scene measured in grid cells or in millimetres is nowhere near where a camera starts, and without this the first thing a caller sees is an empty canvas.