Procedural generation

L-System / Lindenmayer System

Lシステム

記号を置き換えて木や稲妻の分岐を作る。

2 / 10

Interactive demo

Preparing the demo…

L-System / Lindenmayer System

Drag to orbit, Ctrl/⌘ + scroll to zoom. Use two fingers on touch screens.

This explanation is currently available in Japanese.

ひとことで

「X を F[+X][-X] に置き換える」のような文字の書き換え規則をくり返し当てはめて長い文字列を作り、それを亀(タートル)の動きの命令として読んで図形を描く方法です。もともとは植物の成長を表すために考えられたもので(リンデンマイヤー、1968 年)、少ない規則から、木・草・シダ・稲妻のような自己相似な枝分かれの形が作れます。

ゲームでの使いどころ

  • 木や草の生成:幹・枝・葉の出方を規則で書き、種類ごとに規則や角度を変えて、たくさんの種類の木を作る。SpeedTree のような植物生成ツールの考え方の元になっている。
  • 稲妻・ひび割れ:確率つきの規則で、毎回違う形の枝分かれを作る。
  • 道路網・川:分かれ道の規則で、街の道路や川の支流のような形を作る。
  • フラクタルの模様:コッホ曲線やドラゴン曲線など、魔法陣や装飾の模様。

しくみ

書き換え:最初の文字列(公理)に、すべての文字へ同時に規則を当てはめます。

X  →  F[+X][-X]FX,F  →  FF\text{X} \;\to\; \text{F[+X][-X]FX}, \qquad \text{F} \;\to\; \text{FF}

1 回ごとに文字列は何倍にも長くなり、枝の中に同じ形の小さな枝が入れ子になります。

描画(タートル):できた文字列を先頭から読み、位置と向きを持った亀を動かします。

記号動き
F前へ 1 歩進み、線を引く
+ / −左右に角度 δ\delta だけ曲がる
& / ^下 / 上を向く(3D)
/ / \進む向きの軸の周りに回る(3D)
[今の位置と向きをスタックに積む(枝分かれの開始)
]スタックから位置と向きを戻す(枝の終わり)

確率つき L システム:1 つの文字に複数の規則を用意し、確率で選ぶと、同じ規則から毎回少しずつ違う形ができます。

実装のポイント

  • 向きはクォータニオンで:3D では、曲がる・傾く・回るを組み合わせるので、向きをクォータニオンで持ち、自分の軸の周りに回します。
  • 太さと長さ:枝の深さ([ の入れ子の数)で線を細く・短くすると、木らしくなります。線ではなく円柱やスイープで太さのある枝にすれば、そのままゲームの木のメッシュになります。
  • ばらつき:角度に少しの乱数を足すだけで、機械的な形が自然になります。
  • 大きさの管理:回数を 1 増やすと文字列が数倍になるので、回数の上限を決めておきます。完成した形の大きさも変わるので、描く前に全体の大きさを測って縮めます。

つまずきやすい点

  • 形を思いどおりにしにくい:規則を少し変えるだけで形が大きく変わり、「この辺に枝がほしい」といった調整は苦手です。周りの空間に合わせて伸ばしたい場合は空間占有法の方が向いています。
  • 枝どうしの衝突:規則は周りを見ないので、枝どうしが重なったり、地面や壁を突き抜けたりします。
  • 文字列の爆発:回数を増やしすぎると、文字列が数百万文字になり、メモリも時間も足りなくなります。

デモで試すこと

  1. 「3D の木」で「書き換えの回数」を 1 から 5 まで増やし、同じ形の枝が入れ子になっていく(自己相似)様子を確かめてください。数値の「文字列の長さ」が回数ごとに何倍にもなります。
  2. 「曲がる角度」や「角度のばらつき」を変えると、細い針葉樹のような形から、横に広がる形まで変わります。
  3. 「シダ(2D)」は、平面の中だけで曲がる規則です。
  4. 「稲妻」は確率つきの規則なので、打つたびに違う形になります。「コッホ雪片」は、辺を「山を 1 つ作る形」に置き換えるだけで雪の結晶になります。

References

WaveFunctionCollapse ↗

A general reference for this subcategory.