Project: Exploring L-Systems
Introduction
After learning about Mandelbrot, Sierpinski, and Koch fractals, I began looking for more fractals to add to my PlotEquation plugin - especially ones that appeared in nature. After working with fractals for quite some time I started to see them everywhere, from river tributaries to trees during the winter. While browsing through Wikipedia’s entry on fractals, I discovered a grammar-based system of fractals known as Lindenmayer Systems (or L-Systems) that instantly caught my attention. The 2D version was simple enough to implement, as I simply used mathematical concepts I had already learned in high school geometry. However, transitioning to 3D was much more challenging than I expected, as using 3D rotations didn’t quite work as intended: given that 3D rotations are always relative to the X, Y, and Z-axes, I couldn’t use spherical math to rotate a line relative to the orientation of the line before it. To implement such a rotation, I had to learn about gimbal-locks and quaternions - which allowed me to create my own 3D turtle system. After adding that to the grammar-handling code and incorporating it into my PlotEquation plugin, this project could now generate both 2D and 3D L-Systems that can be further manipulated with other CAD softwares.
Features
There are three types of variables: draw, move, and control. The plugin allows the user to be able to choose their own (the L-System’s alphabet), as well as specifying the production rules for each variable.
• Draw variables will command the system to draw a line in the direction its facing, thus modifying the system’s position
• Move variables will command the system to move the system’s position in the direction its facing, without drawing anything
• Control variables will not affect the system’s position in any way, and are only used as a means of incorporating more recursive rules
An L-System also needs to start with a set of variables, known as the axiom. Furthermore, the user will able to control initial values such as the turning angle, line length, line scale, etc, as well as implement advanced production rules such as branching (see this example). Starting from here and recursively applying the production rules for each variable, the L-System is then generated. The acceptable grammar used in this plugin is as follows:
Rotations
Yaw
• Left: +
• Right: -
Pitch
• Up: ^
• Down: &
Roll
• Left: @
• Right: #
Turn Around (yaws by 180°): |
Negate Turning Angle: !
Modifications
Increment Turn Angle
• Up: :
• Down: ;
Increment Line Thickness
• Up: <
• Down: >
Scale Line Length
• Up: *
• Down: /
Scale Line Thickness
• Up: $
• Down: %
Other
Branching
• Push: [
• Pop: ]
Custom Value
• Start: (
• An Evaluable Expression
• End: )
Custom Command
• Start: {
• Argument separation: ,
• End: }
Custom Commands
Copy Production Rule(s) by Pitch (4 arguments)
• 1: “PitchArray”
• 2: Angle to fill (in degrees)
• 3: Number of elements to copy
• 4: Production Rule(s)
Copy Production Rule(s) by Roll (4 arguments)
• 1: “RollArray”
• 2: Angle to fill (in degrees)
• 3: Number of elements to copy
• 4: Production Rule(s)
If Within Probability (2 arguments)
• 1: Probability [0,1]
• 2: Production Rule(s) on Success
If Within Probability, Else (3 arguments)
• 1: Probability [0,1]
• 2: Production Rule(s) on Success
• 3: Production Rule(s) on Failure
Copy Production Rule(s) by Yaw (4 arguments)
• 1: “YawArray”
• 2: Angle to fill (in degrees)
• 3: Number of elements to copy
• 4: Production Rule(s)
Gallery
Variable Key:
• BOLD UPPERCASE: draw variable
• UPPERCASE: move variable
• lowercase: control variable
Naming Key:
• Fractal Name (Iteration #): Axiom; Rules; Initial Conditions
• Note that some images may switch the order around to maintain formatting
• All initial line lengths are 1, and unless otherwise specified, line thickness scale will match line length scale
Random Fractal Weeds (5): F; F→{0.333, F[+F]F[-F]F, {0.5, F[+F]F, F[-F]F}};
Turn Angle: 25.7°
Fractal Weed (5): F; F→F[+F]F[-F]F;
Turn Angle: 25.7°
3D Pythagoras Trees (6): A; A→B*${RollArray, 360, 4, [^A]}, B→B;
Turn Angle: 30°, Line Scale: 0.8, Line Thickness: 0 and 0.1, respectively
3D Fractal Trees, Triangle Base (6): A; A→B*$[A]*$[^A]@(120)[^A]@(120)^A, B→B;
Turn Angle: 30°, Line Scale: 0.8, Line Thickness: 0 and 0.1, respectively
3D Fractal Trees, Square Base (6): A; A→B*$[A]*${RollArray, 360, 4, [^A]}, B→B;
Turn Angle: 30°, Line Scale: 0.8, Line Thickness: 0 and 0.1, respectively
3D Random Fractal Trees (6): A; Line Scale: 0.8, Line Thickness: 0.1
A→B*${.8, [^(randint(-15,15))A]}*${RollArray, randint(270,360), randint(2,4),[^(randint(20,40))A]}, B→B