https://discord.com/channels/581738731934056449/1026221281810579556/1026253177177255957
Last active
March 19, 2023 13:43
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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
