Skip to content

Instantly share code, notes, and snippets.

@uwezi
Last active March 19, 2023 13:43
Show Gist options
  • Save uwezi/4d99ca5851ceb6a039e9774d990f1702 to your computer and use it in GitHub Desktop.
Save uwezi/4d99ca5851ceb6a039e9774d990f1702 to your computer and use it in GitHub Desktop.
[L-system tree] How to build an L-system tree in Manim. #manim #lsystem #dataclasses #artist #tree #animate
# code by @Maieutic
# https://discord.com/channels/581738731934056449/1026221281810579556/1026253177177255957
from dataclasses import dataclass
from manim import *
import numpy as np
L_SYSTEM = {
"axiom": "F",
"rules": {"F": "F[-F][+F]", "+": "+", "-": "-", "[": "[", "]": "]"},
"iterations": 5,
"length": 0.5,
"degrees": 25,
"inital_degrees": 90,
"start": np.array([0, -1, 0]),
}
class Tree(Scene):
def construct(self):
(
axiom,
rules,
iterations,
length,
degrees,
initial_degrees,
start,
) = L_SYSTEM.values()
system = LSystem(axiom, rules, iterations)
artist = LSystemArtist(system, length, degrees, initial_degrees, start)
self.play(Create(artist.tree))
self.wait(2)
class LSystemArtist:
def __init__(self, system, length, degrees, initial_degrees, start):
self.system = system
self.commands = {
"F": self.forward,
"+": self.rotate_left,
"-": self.rotate_right,
"[": self.save,
"]": self.restore,
}
self.theta = initial_degrees * PI / 180
self.rotation = degrees * PI / 180
self.length = length
self.start = start
self.positions = []
self.rotations = []
self.tree = VGroup()
self.draw_system()
def draw_system(self):
for instruction in self.system.instructions:
if instruction in self.commands.keys():
self.commands[instruction]()
def forward(self):
end = (
self.start
+ (self.length * np.cos(self.theta) * RIGHT)
+ (self.length * np.sin(self.theta) * UP)
)
new_line = Line(start=self.start, end=end)
self.start = end
self.tree.add(new_line)
def rotate_left(self):
self.theta += self.rotation
def rotate_right(self):
self.theta -= self.rotation
def save(self):
self.positions.append(self.start)
self.rotations.append(self.theta)
def restore(self):
self.start = self.positions.pop()
self.theta = self.rotations.pop()
class LSystem:
def __init__(self, axiom, rules, iterations):
self.rules = rules
self.iterations = iterations
self.instructions = axiom
self.create_instructions()
def create_instructions(self):
new_string = ""
for _ in range(self.iterations):
new_string = ""
for character in self.instructions:
new_string += self.rules[character]
self.instructions = new_string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment