simetri.extensions.l_system
Lindenmayer system (L-system) module.
1"""Lindenmayer system (L-system) module.""" 2 3from math import ceil 4 5from ..graphics.batch import Batch 6from ..graphics.shape import Shape 7from .turtle_sg import Turtle 8 9 10def l_system( 11 rules: dict, axiom: str, angle: float, dist: float, n: int, d_actions: dict = None 12): 13 """Generate a Lindenmayer system (L-system) using the given rules. 14 15 An L-system is a parallel rewriting system that uses recursive rules to 16 generate complex patterns. This function interprets the generated string 17 as turtle graphics commands. 18 19 Args: 20 rules: A dictionary with characters as keys and strings as values. 21 Each character in the axiom or resulting string will be replaced 22 by its corresponding rule in each iteration. 23 axiom: The initial string to start the L-system. 24 angle: The angle (in degrees) for turtle rotation commands. 25 dist: The distance for turtle forward/backward movement. 26 n: The number of iterations to apply the rules. 27 d_actions: Optional dictionary mapping characters to turtle methods. 28 This allows extending the default command set. 29 30 Returns: 31 Batch: A batch of shapes representing the L-system drawing. 32 33 Example: 34 >>> rules = {'F': 'F+F-F-F+F'} # Koch curve 35 >>> batch = l_system(rules, 'F', 60, 10, 3) 36 """ 37 38 turtle = Turtle(in_degrees=True) 39 turtle.def_angle = angle 40 turtle.def_dist = dist 41 42 actions = { 43 "F": turtle.forward, 44 "B": turtle.backward, 45 "G": turtle.go, 46 "+": turtle.left, 47 "-": turtle.right, 48 "[": turtle.push, 49 "]": turtle.pop, 50 "|": turtle.turn_around, 51 } 52 if d_actions: 53 for key, value in d_actions.items(): 54 method = getattr(turtle, value) 55 actions[key] = method 56 57 def expand(axiom, rules): 58 """Expand the axiom using the provided rules. 59 60 Args: 61 axiom: The string to expand. 62 rules: Dictionary of replacement rules. 63 64 Returns: 65 str: The expanded string after applying the rules. 66 """ 67 return "".join([rules.get(char, char) for char in axiom]) 68 69 for _ in range(n): 70 axiom = expand(axiom, rules) 71 72 for char in axiom: 73 actions.get(char, lambda: None)() 74 75 # TikZ gives memory error if there are too many vertices in one shape 76 shapes = Batch() 77 # tot = len(turtle.current_list) 78 # part = 200 # partition size 79 # for i in range(ceil(tot/part)): 80 # shape = Shape(turtle.current_list[i*part:(i+1)*part]) 81 # shapes.append(shape) 82 if turtle.current_list: 83 turtle.lists.append(turtle.current_list) 84 for x in turtle.lists: 85 shapes.append(Shape(x)) 86 return shapes 87 88 89# rules = {} 90# rules['F'] = '-F+F+G[+F+F]-' 91# rules['G'] = 'GG' 92 93# axiom = 'F' 94# angle = 60 95# dist = 15 96# n=4 97 98# l_system(rules, axiom, angle, dist, n) 99 100# Examples 101 102# rules = {} 103# rules['X'] = 'XF+F+XF-F-F-XF-F+F+F-F+F+F-X' 104# axiom = 'XF+F+XF+F+XF+F' 105# angle = 60 106# n=2 107 108 109# rules = {} 110# rules['X'] = 'F-[[X]+X]+F[+FX]-X' 111# rules['F'] = 'FF' 112# axiom = 'X' 113# angle = 25 114# n=6 115 116# rules = {} 117# rules['A'] = '+F-A-F+' # Sierpinsky 118# rules['F'] = '-A+F+A-' 119# axiom = 'A' 120# angle = 60 121# n = 7 122 123# rules = {} 124# rules['F'] = 'F+F-F-F+F' # Koch curve 1 125# axiom = 'F' 126# angle = 60 127# n = 6 128 129# rules = {} 130# rules['X'] = 'X+YF+' # Dragon curve 131# rules['Y'] = '-FX-Y' 132# axiom = 'FX' 133# angle = 90 134# n=10 135 136 137# rules = {} 138# rules['X'] = 'F-[[X]+X]+F[+FX]-X' # Wheat 139# rules['F'] = 'FF' 140# axiom = 'X' 141# angle = 25 142# n=6 143 144# rules = {} 145# axiom = 'F+F+F+F' 146# rules['F'] = 'FF+F-F+F+FF' 147# angle = 90 148# n=4
def
l_system( rules: dict, axiom: str, angle: float, dist: float, n: int, d_actions: dict = None):
11def l_system( 12 rules: dict, axiom: str, angle: float, dist: float, n: int, d_actions: dict = None 13): 14 """Generate a Lindenmayer system (L-system) using the given rules. 15 16 An L-system is a parallel rewriting system that uses recursive rules to 17 generate complex patterns. This function interprets the generated string 18 as turtle graphics commands. 19 20 Args: 21 rules: A dictionary with characters as keys and strings as values. 22 Each character in the axiom or resulting string will be replaced 23 by its corresponding rule in each iteration. 24 axiom: The initial string to start the L-system. 25 angle: The angle (in degrees) for turtle rotation commands. 26 dist: The distance for turtle forward/backward movement. 27 n: The number of iterations to apply the rules. 28 d_actions: Optional dictionary mapping characters to turtle methods. 29 This allows extending the default command set. 30 31 Returns: 32 Batch: A batch of shapes representing the L-system drawing. 33 34 Example: 35 >>> rules = {'F': 'F+F-F-F+F'} # Koch curve 36 >>> batch = l_system(rules, 'F', 60, 10, 3) 37 """ 38 39 turtle = Turtle(in_degrees=True) 40 turtle.def_angle = angle 41 turtle.def_dist = dist 42 43 actions = { 44 "F": turtle.forward, 45 "B": turtle.backward, 46 "G": turtle.go, 47 "+": turtle.left, 48 "-": turtle.right, 49 "[": turtle.push, 50 "]": turtle.pop, 51 "|": turtle.turn_around, 52 } 53 if d_actions: 54 for key, value in d_actions.items(): 55 method = getattr(turtle, value) 56 actions[key] = method 57 58 def expand(axiom, rules): 59 """Expand the axiom using the provided rules. 60 61 Args: 62 axiom: The string to expand. 63 rules: Dictionary of replacement rules. 64 65 Returns: 66 str: The expanded string after applying the rules. 67 """ 68 return "".join([rules.get(char, char) for char in axiom]) 69 70 for _ in range(n): 71 axiom = expand(axiom, rules) 72 73 for char in axiom: 74 actions.get(char, lambda: None)() 75 76 # TikZ gives memory error if there are too many vertices in one shape 77 shapes = Batch() 78 # tot = len(turtle.current_list) 79 # part = 200 # partition size 80 # for i in range(ceil(tot/part)): 81 # shape = Shape(turtle.current_list[i*part:(i+1)*part]) 82 # shapes.append(shape) 83 if turtle.current_list: 84 turtle.lists.append(turtle.current_list) 85 for x in turtle.lists: 86 shapes.append(Shape(x)) 87 return shapes
Generate a Lindenmayer system (L-system) using the given rules.
An L-system is a parallel rewriting system that uses recursive rules to generate complex patterns. This function interprets the generated string as turtle graphics commands.
Arguments:
- rules: A dictionary with characters as keys and strings as values. Each character in the axiom or resulting string will be replaced by its corresponding rule in each iteration.
- axiom: The initial string to start the L-system.
- angle: The angle (in degrees) for turtle rotation commands.
- dist: The distance for turtle forward/backward movement.
- n: The number of iterations to apply the rules.
- d_actions: Optional dictionary mapping characters to turtle methods. This allows extending the default command set.
Returns:
Batch: A batch of shapes representing the L-system drawing.
Example:
>>> rules = {'F': 'F+F-F-F+F'} # Koch curve >>> batch = l_system(rules, 'F', 60, 10, 3)