Live

shape(...) --- Make a Shape

shape() draws a shape into the score while it runs, for building a score live from the live console. One cue covers every regular polygon; sides: says which.

sides: shape
0 circle
1 line
2 lens (two arcs)
3 triangle
4 square
5, 6, … pentagon, hexagon, …

Syntax

shape(sides:3) shape(sides:5, size:0.12, at:[0.75, 0.3], fill:#f60) shape(uid:sh1, remove:1) shape(remove:all)

Parameters

param default description
uid made up Its name. The live console writes one in (sh1, sh2, …) the first time.
sides 3 See the table above. rand(3, 8) works.
m, n1, n2, n3 1 A superformula form instead of a polygon — stars, flowers, blobs. See Forms. Each can be a follow().
morph Beats to glide from the outline it has to the one this run gives it — form, sides, size and place. See Morph.
size 0.1 Diameter, as a fraction of the screen: of the shorter side of the band between the top bar and the transport, so 1 just fits. [w, h] stretches it: w of the band's width, h of its height — a wide, flat triangle; a circle becomes an ellipse.
at [0.5, 0.5] Where on screen: 0..1 across, and 0..1 down the band between the top bar and the transport. One number is both: at:0.25 is [0.25, 0.25].
cell A cell of the stage's grid (grid()) instead of at:: 0.8 of the cell's shorter side, size: and at: then shares of the cell; across: and down: span more. On a cluster each member rolls its own: shape(n:6, cell:free) deals one to each empty cell.
fill none Fill colour, or scope: its sound drawn inside it (see below). choose(black, white) picks one each run (each member of a cluster its own).
stroke dark (light in dark mode) Line colour. choose(...) works here too.
width 2 Line width in screen pixels; it stays the same at any zoom.
opacity 1
blend normal How it mixes with what is under it: difference (flips what it crosses: white over white is black, over black is white), exclusion, screen (adds light), multiply (adds ink), overlay, lighten, darken, color-dodge, color-burn, hard-light, soft-light, hue, saturation, color, luminosity; normal or 0 back. shape(n:8, ..., fill:#fff, blend:difference) — overlapping shapes cut each other out.
remove 1 takes the shape with this uid away, with its animations; all takes every made shape away.

Behaviour

Forms — m:, n1:, n2:, n3:

Four numbers give a whole family of shapes beyond the polygons: the superformula (Johan Gielis). Any of them written makes the shape a form; sides: alone makes it a polygon again.

shape(m:5, n1:0.3, n2:0.3, n3:0.3) a five-pointed star shape(m:6, n1:1, n2:7, n3:8) a six-petalled flower shape(m:3, n1:4.5, n2:10, n3:10) a soft triangle shape(m:4, n1:12, n2:15, n3:15) a cushion shape(m:12, n1:0.2, n2:1.7, n3:1.7) a cog shape(m:8, n1:0.5, n2:0.5, n3:8) a cross with barbs

m how many times it repeats round: points, petals, lobes. 0 is a circle. Between two whole numbers (2.5) it is the mix of the two.
n1 how round: small (0.2) pinches it into sharp points, large (10) swells it out
n2, n3 the shape of each side; equal to each other, a symmetrical one. m:4, n1:2, n2:2, n3:2 is a circle.

Any of them can follow a signal, and the form moves with it:

shape(uid:bloom, m:follow(bass.low, 2, 9), n1:follow(bass.level, 0.2, 3), size:0.4, stroke:#fff)

A form is as big as size: says, whatever the numbers: the farthest point is on the size's edge. It turns, scatters and fills with its sound (fill:scope) like any shape.

Morph — morph:

Run a shape again with morph: and it glides from the outline it has to the new one over that many beats — between any two of circles, polygons and forms, its size and its place too:

shape(uid:a, sides:3, size:0.3) shape(uid:a, m:5, n1:0.3, n2:0.3, n3:0.3, morph:2) triangle into a star over 2 beats shape(uid:a, sides:0, size:0.5, at:[0.3, 0.5], morph:4) ... into a big circle, moving left

Every outline is said as its distance from the middle all round, and a morph mixes the two angle by angle, so it never tears or jumps. A morph started mid-morph starts from where the last one has got to. Lines and lenses (sides:1, 2) change at once.

Clusters — n:

n: makes a cluster: that many shapes from one line, each with its own roll of every rand() in it -- the line's animations included.

shape(n:12, sides:irand(3, 8), size:rand(0.03, 0.12), at:[rand(0.1, 0.9), rand(0.2, 0.8)]) rotate(dur:rand(2, 9), loop:0)

A shape's sound — self

A shape publishes where it was put: <uid>.x and <uid>.y, 0..1 across and down the screen (and its rotation publishes angle, sin, cos, tvel …). Anything else on the shape's line can follow it through self (me works too), which stands for the shape -- in a cluster, for each member:

shape(uid:choir, n:12, at:[rand(0.1, 0.9), rand(0.2, 0.8)]) rotate(dur:rand(2, 9), loop:0) synth(wave:saw, freq:follow(self.y, 900, 90), pan:follow(self.x, -1, 1), filter:{type:lp, freq:follow(self.tvel, 200, 4000), q:6}, amp:0.02, waveform:none)

Twelve shapes, twelve voices: each one's pitch from how high it is, its pan from how far left or right, its brightness from how fast it turns. A sound on a shape's line is named after the shape (each member its own voice), goes when the shape is removed, and hush(choir) silences a whole cluster. waveform:none keeps twelve scope boxes off the screen.

Its sound inside it — fill:scope

shape(uid:choir, n:12, sides:irand(0, 8), size:rand(0.08, 0.2), at:[rand(0.1, 0.9), rand(0.3, 0.8)], fill:scope, stroke:#f6f740) rotate(dur:rand(2, 9), loop:0) synth(wave:saw, freq:follow(self.y, 900, 90), amp:0.02, waveform:none)

Each member draws its own voice across itself, clipped to its outline, in its stroke colour (and line width), turning and moving with it. A line (sides:1) has no inside: the trace is the line. gui(choir, view:polar) (or phase, spectrum) draws it another way; gui(choir, trail:2) lets it smear. A shape with no sound of its name shows a flat line; another fill: colour puts the solid fill back.

Examples

// a triangle whose turning pans a synth shape(sides:3, size:0.15) rotate(dur:4, loop:0) synth(uid:s2, freq:rand(100, 400), pan:follow(sh1.sin, -1, 1))

shape(sides:0, size:0.07, at:[0.6, 0.75], stroke:#0aa, width:4) shape(sides:rand(3, 8), size:rand(0.05, 0.15), at:[rand(0.1, 0.9), rand(0.2, 0.8)])

Changing colour and size as it goes — color(), scale()

A shape is drawn once each time its line runs. It has no dur:, so a pattern written into it (fill:Prand(black, white, inf)) gives one value per run, as choose() does. A colour that keeps changing comes from color() on the same line: its dur: is the time each value is held.

shape(uid:sh1, sides:3, size:0.4) color(vals:Prand([black, white], inf), dur:0.5, mode:step, target:fill)

Size the same way, with scale() (a factor of the shape's size:; interp:step jumps, without it the size glides):

sh1 > scale(values:Prand([0.5, 1, 1.5], inf), dur:0.3, interp:step) sh1 > scaleXY(Prand([0.5, 1.5], inf), Prand([0.5, 1.5], inf), dur:0.3, interp:step)

The second stretches it: width and height drawn apart. gui(sh1, trail:2) lets every turn and change of size leave a fading tail.

mode:step switches between colours; without it the colour glides from one to the next. target:stroke changes the line instead, and leaving target: out changes both. Running the shape() again with a fill: or stroke: puts that colour back.

Tip: use ← → or ↑ ↓ to navigate the docs