Generative art
Tools for work where chance decides the picture: a seed you control (and that travels inside every PNG), a sheet of variations to choose from, and an export that turns the chosen one into a print-quality PNG, an SVG, or paths for a pen plotter.
On this page · 5 entries
Seed · RandomSeed · NoiseSeed
Seed → intRandomSeed(seed)NoiseSeed(seed)
Every sketch has a seed: Random(), RandomGaussian(), Noise(), PVector.Random2D() and list Shuffle() all follow it, so the same seed draws the same picture. The IDE picks one before Setup() — a new one per Run — and shows it in the status bar. RandomSeed(Seed) at the top of Draw() makes every frame repeat the same numbers, so a [Tweak] slider changes only what it controls.
Save(), SaveFrame()) carries its seed, frame and [Tweak] values inside, and Sketch → Open seed from PNG... brings them back: the same image again. Randomness from new System.Random() or Random.Shared doesn't follow the seed.Variations sheet Ctrl+Shift+V
Sketch → Variations sheet draws the sketch 9 or 16 times side by side: each with its own seed, its own [Tweak] values (random inside each slider's range) or both, after the first frame or after 1–3 seconds of animation. Click the best one: its seed is locked and its values go back into the running sketch — then Apply tweaks to code writes them into the source. Like a contact sheet for generative work: you choose instead of rolling the dice one Run at a time.
VariationRenderer.Plan(...) makes the list of seeds/values and VariationRenderer.Render(...) draws each one offscreen into a PImage, without touching the running sketch.Export for print · SVG for plotters Ctrl+Shift+E
File → Export for print redraws the sketch from scratch — same seed and [Tweak] values, after as many frames as you choose — as vectors, so it is sharp at any size. Three outputs:
| Output | What you get |
|---|---|
| PNG, 2x–16x | A poster-sized PNG rendered band by band, so even 16x never has to fit in memory. Carries the seed and values inside, like every PNG a sketch saves. |
| SVG | The drawing as vectors for Illustrator, Inkscape or a laser cutter. |
| SVG for a plotter | One Inkscape layer per stroke color (one pen each), backgrounds dropped, fills turned into outlines, and the strokes reordered — and reversed when that's shorter — so the pen travels as little as possible in the air. |
PrintExport.SavePng(factory, seed, tweaks, frames, scale, path), PrintExport.SaveSvg(...) and PlotterSvg.Optimize(svg) are public. Sketches that read pixels back (LoadPixels(), Get()) can't be recorded as vectors; they're exported as pixels at the big size and the IDE says so.Runnable example: seeded landscapes
A landscape made only with Random() and Noise(): F6 rolls another seed, Ctrl+Shift+V opens the variations sheet, and S saves a PNG you can reopen with Sketch → Open seed from PNG. Test in Dana opens it in the IDE, or paste it into a new tab and press Run. It is also in Sketch → Examples.
// Seeded generative art: same seed, same landscape. // // Everything random here comes from Random() and Noise(), which follow the // sketch's Seed -- so: // F6 (🎲) a new seed (Sketch menu: keep the seed to lock it) // Ctrl+Shift+V the variations sheet: pick the best of 9 or 16 // S save a PNG; it remembers the seed and the sliders // (Sketch > Open seed from PNG... brings them back) // // RandomSeed(Seed) at the top of Draw() makes every frame repeat the same // random numbers, so moving a slider changes only what that slider controls. public class MySketch : Sketch { [Tweak(2, 8)] int layers = 5; [Tweak(0.5f, 6)] float roughness = 2.2f; [Tweak(0, 360)] float hue = 215; [Tweak(0, 400)] int stars = 160; [Tweak] bool sun = true; public override void Setup() => Size(800, 500); public override void Draw() { RandomSeed(Seed); // Sky: a vertical gradient. for (int y = 0; y < Height; y += 4) { float t = y / (float)Height; FillHSB(hue, 50 - t * 20, 18 + t * 30); NoStroke(); Rect(0, y, Width, 4); } // Stars. for (int i = 0; i < stars; i++) { float x = Random(Width), y = Random(Height * 0.6f); Fill(255, Random(80, 230)); Circle(x, y, Random(1, 3)); } // Sun (or moon). if (sun) { FillHSB((hue + 180) % 360, 40, 100, 230); Circle(Random(120, Width - 120), Random(80, 200), Random(60, 120)); } // Mountain layers, back to front: lighter and smoother far away. for (int layer = 0; layer < layers; layer++) { float depth = layer / (float)Math.Max(1, layers - 1); float baseY = Height * (0.45f + depth * 0.4f); float amp = 60 + depth * 90; float offset = Random(1000); FillHSB(hue, 35 + depth * 30, 70 - depth * 55); BeginShape(); Vertex(0, Height); for (int x = 0; x <= Width; x += 6) Vertex(x, baseY - Noise(offset + x * 0.004f * roughness, layer * 10) * amp * 2 + amp); Vertex(Width, Height); EndShape(true); } Fill(255, 200); TextSize(13); Text($"seed {Seed} · F6 new seed · Ctrl+Shift+V variations · S save PNG", 14, Height - 14); } public override void KeyPressed() { if (Key == 's') { HideTweaks(); SaveFrame($"landscape-{Seed}-####.png"); ShowTweaks(); Println($"Saved landscape-{Seed}-{FrameCount:0000}.png (seed and sliders are inside the PNG)"); } } }
Runnable example: flow lines for a plotter
Hundreds of strokes following a Noise() field in two colors — export it with Ctrl+Shift+E as an SVG for a plotter (one layer per pen) or as an 8x PNG. Test in Dana opens it in the IDE, or paste it into a new tab and press Run. It is also in Sketch → Examples.
// Plotter-friendly art: only strokes, two pens. // // File > Export for print (Ctrl+Shift+E): // "Plotter SVG" one layer per color (= per pen), strokes reordered so the // pen travels as little as possible between them // "Big PNG" 2x-16x, drawn again as vectors: sharp at poster size // Same seed, same drawing -- F6 rolls another one. public class MySketch : Sketch { [Tweak(50, 900)] int lines = 420; [Tweak(10, 160)] int steps = 70; [Tweak(0.5f, 6)] float zoom = 2.2f; [Tweak(0, 1)] float secondPen = 0.25f; public override void Setup() { Size(700, 500); FrameRate(12); // a still drawing: a few frames a second is plenty for the sliders } public override void Draw() { RandomSeed(Seed); Background(250, 248, 240); NoFill(); StrokeWeight(1); for (int i = 0; i < lines; i++) { float x = Random(-50, Width + 50); float y = Random(-50, Height + 50); bool red = Random(1) < secondPen; if (red) Stroke(200, 40, 40); else Stroke(20, 20, 30); BeginShape(); for (int s = 0; s < steps; s++) { Vertex(x, y); float angle = Noise(x / Width * zoom, y / Height * zoom) * TWO_PI * 2; x += Cos(angle) * 4; y += Sin(angle) * 4; } EndShape(); } } }