Appearance
Scientific geometry
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): voidDraw the tubes
handlenames.plot.uploadTubes(paths: Paths, radius: number, colour: Colour | Hex): TubesHandleUpload 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.
radiusis in world units, and a per-pointwidthscolumn 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): voidDraw the ribbons
handlenames.plot.uploadRibbons(paths: Paths, width: number, colour: Colour | Hex): RibbonsHandleUpload a set of curves swept into flat ribbons, and return a handle naming them.
The columns are a tube's, and
widthis 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(): voidPoint 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.