01 · Problem
Wofür braucht man das?
Pflanzen, Fraktale und prozedurale Formen lassen sich kompakt als Axiom plus lokale Umschreibregeln beschreiben.
02 · Denkmodell
Das mentale Modell
Jede Generation liest ausschließlich die vorherige Symbolfolge und baut eine neue. Stochastische Regeln wählen pro Symbol eine Transformation aus einer validierten Gewichtsverteilung.
Schreibt Symbolfolgen mit normalisierten Gewichten und austauschbarer Zufallsquelle um. Ausgabe kann exponentiell wachsen. Rendering und anwendungsspezifische Ausgabelimits sind von der Grammatik getrennt.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- Regeln einmal nach Ursprungssymbol gruppieren und Gewichte validieren.
- Für jede Iteration eine frische Ausgabefolge erzeugen.
- Für jedes Symbol eine Regel über injizierten Zufall wählen oder es unverändert übernehmen.
- Transformationssymbole einzeln anhängen und vor einem Größenlimit stoppen.
04 · Bauteile
Die entscheidenden Verträge
LSystem / generateSchreibt ein Axiom mit validierten gewichteten Regeln um.Rule / SymbolTypeBeschreibt Symbole, Ersetzungen und relative Gewichte.05 · Selbst bauen
Selbst implementieren
Nutze Symbolarrays statt impliziter String-Coercion und injiziere Zufall für reproduzierbare Generationen.
- Indiziere Regeln pro Symbol und normalisiere positive Gewichte.
- Erzeuge jede Generation aus einem unveränderten Snapshot der vorherigen.
- Begrenze Iterationen und maximale Symbolzahl vor unkontrolliertem Wachstum.
type Rule<S> = { weight: number; replacement: readonly S[] };
function expand<S>(
input: readonly S[],
rules: ReadonlyMap<S, readonly Rule<S>[]>,
random: () => number,
) {
const output: S[] = [];
for (const symbol of input) {
const rule = chooseWeighted(rules.get(symbol) ?? [], random());
output.push(...(rule?.replacement ?? [symbol]));
}
return output;
}06 · Verifizieren
Was solltest du testen?
- Deterministischer RNG erzeugt erwartete Generationen und Randgewichte.
- Symbole ohne Regel bleiben erhalten; mehrere Ersatzsymbole enthalten keine Kommas.
- Ungültige Gewichte und Überschreiten des Größenlimits führen zu klaren Fehlern.
Selbst ausprobieren
Formuliere die erste Prüfaussage als fehlschlagenden Test, implementiere die kleinste Korrektur und ergänze einen Grenzfall.
Deterministischer RNG erzeugt erwartete Generationen und Randgewichte.
Ansatz vergleichen
Dein Test sollte beim gezielten Verletzen der Invariante fehlschlagen und nach der Korrektur wieder bestehen. Halte den Aufbau deterministisch und prüfe ein beobachtbares Ergebnis.
07 · Grenzen
Kompromisse und Stolperfallen
- Materialisierte Folgen können exponentiell wachsen; Streaming erschwert spätere Generationen.
- Stochastische Ergebnisse sind ohne Seed nicht reproduzierbar.
Ausgabe kann exponentiell wachsen. Rendering und anwendungsspezifische Ausgabelimits sind von der Grammatik getrennt.
08 · Weiterdenken
Quellcode und verwandte Ideen
yarn tsx packages/lsystem/examples/basic.ts