© 2025 STUDIO TAMA

✅ Inputs
- axiom: str – 初期文字列(例: `"F"`)
- rules: dict – 書き換えルール(例: `{"F": "F[+F][-F][^F][&F][\\F][/F]"}`)
- angle: float – 各回転の角度(度)
- base_length: float – 初期の枝の長さ
- depth: int – ルール展開の反復回数(再帰深度)
- decay: float – 各分岐で枝が短くなる比率(0.8 など)
- pipe_radius: float – Pipeの太さ✅ Outputs
- results: list of Brep – 3D空間に立体的に分岐するL-System構造をPipeで可視化したもの✅ Code
import Rhino.Geometry as rg
import math
# === 🔧 入力パラメータ例(全方向への分岐)
axiom = "F"
rules = {
"F": "F[+F][-F][^F][&F][\\F][/F]" # 全方向へバランスよく分岐
}
angle = 40.0 # 回転角度(度)
base_length = 100.0 # 初期枝の長さ
depth = 4 # 再帰深度
decay = 0.8 # 枝の長さ減衰率
pipe_radius = 1.0
# === 🧬 L-Systemの展開
def expand_lsystem(axiom, rules, depth):
result = axiom
for _ in range(depth):
next_result = ""
for char in result:
next_result += rules.get(char, char)
result = next_result
return result
# === 🐢 Turtle描画(3D Turtle with Length Decay)
def interpret_lsystem(lsys_string, angle_deg, base_length, decay):
pos_stack = []
dir_stack = []
up_stack = []
right_stack = []
length_stack = []
pos = rg.Point3d(0, 0, 0)
dir = rg.Vector3d(0, 0, 1) # Z方向に伸びる
up = rg.Vector3d(1, 0, 0) # X軸方向
right = rg.Vector3d(0, 1, 0) # Y軸方向
length = base_length
lines = []
angle_rad = math.radians(angle_deg)
for char in lsys_string:
if char == "F":
new_pos = pos + dir * length
lines.append(rg.Line(pos, new_pos))
pos = new_pos
elif char == "+":
xform = rg.Transform.Rotation(angle_rad, up, pos)
dir.Transform(xform)
elif char == "-":
xform = rg.Transform.Rotation(-angle_rad, up, pos)
dir.Transform(xform)
elif char == "&":
xform = rg.Transform.Rotation(angle_rad, right, pos)
dir.Transform(xform)
elif char == "^":
xform = rg.Transform.Rotation(-angle_rad, right, pos)
dir.Transform(xform)
elif char == "\\":
xform = rg.Transform.Rotation(angle_rad, dir, pos)
up.Transform(xform)
right.Transform(xform)
elif char == "/":
xform = rg.Transform.Rotation(-angle_rad, dir, pos)
up.Transform(xform)
right.Transform(xform)
elif char == "[":
pos_stack.append(rg.Point3d(pos))
dir_stack.append(rg.Vector3d(dir))
up_stack.append(rg.Vector3d(up))
right_stack.append(rg.Vector3d(right))
length_stack.append(length)
length *= decay # 枝を短くする
elif char == "]":
pos = pos_stack.pop()
dir = dir_stack.pop()
up = up_stack.pop()
right = right_stack.pop()
length = length_stack.pop()
return [l.ToNurbsCurve() for l in lines]
# === 🚀 実行
lsys_string = expand_lsystem(axiom, rules, depth)
curves = interpret_lsystem(lsys_string, angle, base_length, decay)
results = []
for c in curves:
pipes = rg.Brep.CreatePipe(c, pipe_radius, False, rg.PipeCapMode.Round, True, 0.001, 0.001)
if pipes:
results.extend(pipes)ライセンス・利用規約
| 項目 | 可否 | 説明 |
|---|---|---|
| 自身のプロジェクトへの組み込み | ○ | 個人・商用問わず、スクリプトや作品の一部として自由に使えます。 |
| コードの改変・学習利用 | ○ | 自身の学習や、目的に合わせたカスタマイズは大歓迎です。 |
| SNSへのシェア・紹介 | ○ | 作品の画像やURLのシェアは許可不要です。ぜひご紹介ください! |
| 再配布・転載 | × | コードやファイルを丸ごと自身のサイト等でコンテンツとして公開しないでください。 |
| 素材・プログラムとしての転売 | × | 本サイトの内容をそのまま、あるいは微調整のみで有料販売しないでください。 |
| 著作権表示・リンク | 任意 | 必須ではありませんが、引用元としてリンクを貼っていただけると励みになります。 |