How it works
L-System(リンデンマイヤーシステム)は、1968 年に植物学者 Aristid Lindenmayer が提唱した並列書き換え文法です。単純な文字列の置換規則を繰り返し適用するだけで、植物の枝分かれやフラクタル構造といった複雑な自己相似パターンが生まれます。
文法と書き換え規則
L-System は「公理」(初期文字列)と「置換規則」の組で定義されます。たとえば代表的なフラクタル植物の規則は以下の通りです。
公理: X
規則: X → F+[[X]-X]-F[-FX]+X
F → FF
各反復ですべての文字が同時に置換されます(並列書き換え)。反復 1 回目で数文字だった文字列が、7 回の反復で数万〜数十万文字に指数的に成長します。
function expandLSystem(axiom: string, rules: Record<string, string>, iterations: number) {
let current = axiom;
for (let i = 0; i < iterations; i++) {
let next = "";
for (const ch of current) {
next += rules[ch] ?? ch;
}
current = next;
if (current.length > 2_000_000) break; // 安全上限
}
return current;
}タートルグラフィクス
生成された文字列を「亀」が解釈して描画します。
F/G— 前進しながら線を引く+— 左に回転-— 右に回転[— 現在の位置と角度をスタックに保存(枝分かれの開始)]— スタックから復元(枝分かれの終了)
[ と ] のペアが木の枝分かれを表現する核心です。枝の先端で [ が現れるたびに新しい枝が分岐し、] で親の枝に戻ります。
シードによるバリエーション
このデモでは mulberry32 アルゴリズムによるシード付き疑似乱数を使い、8 種類のテンプレート(フラクタル植物、しだれ柳、シダなど)からランダムに選択し、角度や規則に微妙な突然変異を加えています。同じシードなら常に同じ木が生成される決定性を保ちつつ、膨大なバリエーションを生み出します。
描画
線分は OGL(WebGL ラッパーライブラリ)で三角形ペア(クアッドストリップ)に変換されて GPU 描画されます。枝の深さに応じて線幅が細くなり、色は幹(茶色)から先端の花(桜色)へグラデーションします。
// 枝の深さで線幅を調整
const depthFade = 0.08 + 0.92 * (1 - branchDepth / maxDepth);
const width = lineWidth * 0.0012 * depthFade;成長アニメーション
反復レベル 1 から始まり、一定間隔で次のレベルに進むことで木が「成長」するアニメーションを表現しています。各レベル内でも smoothstep でセグメントを徐々に描画し、なめらかな伸長を実現しています。