This project explores the use of the Lindenmayer System of Fractals to model tree-like fractal structures with varying branching patterns, iterations, and angular deviations in both 2D and 3D. I explore how the parameters of branching affects the overall measurable metrics of the tree, analyze the results of changing L-System rules and create a function to allow for generation of Stochastic 2D & 3D L-System Trees.
Introduction
Introduction
Natural trees exhibit remarkable structural complexity, shaped by genetic rules and influenced by their environment. From branching patterns to asymmetrical crowns, no two trees are exactly alike, yet there are underlying systems that govern their growth. In this computational essay, I explore how these biological phenomena can be modeled using Lindenmayer systems (L-System), a recursive, string-based rule used to simulate plant development.
While deterministic L-systems produce elegant, rule-based forms, they often lack the variation and irregularity characteristic of real trees. To address this, I developed stochastic L-system functions in both 2D and 3D, introducing random angles and segment lengths to create more natural, varied structures. I further analyzed these trees by examining their convex hulls to quantify crown spread and compare different branching patterns.
While deterministic L-systems produce elegant, rule-based forms, they often lack the variation and irregularity characteristic of real trees. To address this, I developed stochastic L-system functions in both 2D and 3D, introducing random angles and segment lengths to create more natural, varied structures. I further analyzed these trees by examining their convex hulls to quantify crown spread and compare different branching patterns.
Lindenmayer Fractal system
Lindenmayer Fractal system
L-systems describe how living things can develop complex forms by the repeated application of simple rules. Aristid Lindenmayer (1925–1989), the theoretical biologist who proposed L-systems in 1968, first used them to describe the growth patterns of algae.
In L-system, structures develop through a process of string rewriting. A string of letters is transformed into a new string using simple rules called productions. The process is repeated through a number of iterations, each time using the string that was just produced as the source for the next string. Because the strings grow with each rewrite, an L-system can become arbitrarily complex, but always guided by a simple process dictated by a fixed set of rules.
In L-system, structures develop through a process of string rewriting. A string of letters is transformed into a new string using simple rules called productions. The process is repeated through a number of iterations, each time using the string that was just produced as the source for the next string. Because the strings grow with each rewrite, an L-system can become arbitrarily complex, but always guided by a simple process dictated by a fixed set of rules.
Initialization
Initialization
2D L-System Trees
2D L-System Trees
Function
Function
This implementation of an L-system simulates branching patterns using a procedural drawing approach similar to turtle graphics (in the Logo programming language). The system interprets a symbolic string using geometric instructions to draw fractal trees.
In the Wolfram Language, the function can be used to expand the string, which is then interpreted character by character as commands for a “virtual turtle” that moves and turns in 2D space. The turtle maintains a position and heading (angle), and its movement traces out branches. To do this I used the Wolfram Function Repository Resource Function which is a modern implementation of Lindenmayer’s formal grammar system.
In the Wolfram Language, the
SubstitutionSystem
LSystem
Rule:
Rule:
◼
A (Any Constant) → Forward
◼
[ → Open New Branch
◼
] → Close Branch
◼
+ → Rotate Clockwise
◼
- → Rotate Counterclockwise
Branches
Branches
2 Branch 2D L-System Tree
2 Branch 2D L-System Tree
The 2 Branch L-System’s rule works with the main branch “A” creating two branches, one rotated left (-) and one right (+), each growing “BA” recursively. This tree is set to 5 iterations with a branch angle of 35 Degrees
Define an L-System rule and generate 2 branch L-System tree:
branchRule={"A"->"A[-BA][+BA]"};branches = Lookup[ResourceFunction["LSystem"][branchRule, "A", 5, 35],"Branches"];Graphics[Line[branches]]
Out[]=
3 Branch 2D L-System Tree
3 Branch 2D L-System Tree
The 3 Branch L-System’s rule works with the main branch “A” creating three branches, one rotated left (-), one right (+) and one straight “BA”, each growing recursively. This tree is set to 5 iterations with a branch angle of 35 Degrees
Define an L-System rule and generate 3 branch L-System tree:
branchRule={"A"->"B[-A][+A]BA","B"->"BB"};branches = Lookup[ResourceFunction["LSystem"][branchRule, "A", 5, 35], "Branches"];Graphics[Line[branches]]
Out[]=
4 Branch 2D L-System
4 Branch 2D L-System
The 4 Branch L-System’s rule works with the main branch “A” creating four branches, 2 rotated left (-, --), and 2 right (+, ++) each growing recursively. This tree is set to 5 iterations with a branch angle of 17 Degrees
In[]:=
branchRule={"A"->"A[--A][-A][+A][++A]"};branches = Lookup[ResourceFunction["LSystem"][branchRule, "A", 5, 17], "Branches"];Graphics[Line[branches]]
Out[]=
5 Branch 2D L-System
5 Branch 2D L-System
The 5 Branch L-System’s rule works with the main branch “A” creating five branches, two rotated left (-, --), two right (+, ++), and one branch going straight ahead, each growing recursively. This tree is set to 5 iterations with a branch angle of 35 Degrees
Define an L-System rule and generate 5 branch L-System tree:
branchRule={"A"->"B[-A][+A][--A][++A]BA","B"->"BB"};branches = Lookup[ResourceFunction["LSystem"][branchRule, "A", 5, 35], "Branches"];Graphics[Line[branches]]
Out[]=
6 Branch 2D L-System
6 Branch 2D L-System
The 6 Branch L-System’s rule works with the main branch “A” creating six branches, three rotated left (-, --, ---), and three right (+, ++, +++) each growing recursively. This tree is set to 3 iterations with a branch angle of 9 Degrees
branchRule={"A"->"A[---A][--A][-A][+A][++A][+++A]"};branches = Lookup[ResourceFunction["LSystem"][branchRule, "A", 3, 9], "Branches"];Graphics[Line[branches]]
7 Branch 2D L-System
7 Branch 2D L-System
The 7 Branch L-System’s rule works with the main branch “A” creating seven branches, three rotated to the left (-, --, ---), three to the right (+, ++, +++), and one continuing straight ahead. In the visualization both trees are generated with 5 iterations and a branching angle of 35°. To highlight the structural layering, the tree on the right is rendered with 25% opacity, allowing the overlapping parts to be seen more clearly against the fully opaque version on the right.
Define an L-System rule and generate 7 branch L-System tree:
branchRule={"A"->"AA[+A][-A][++A][--A][+++A][---A]"};branches = Lookup[ResourceFunction["LSystem"][branchRule, "A", 5, 35], "Branches"];Row[{Graphics[Line[branches]], Graphics[{Opacity[0.25],Line[branches]}]}]
2D-L-System Tree Visualizer
2D-L-System Tree Visualizer
To compare different trees based on differing L-system parameters, I created a 2D Tree Visualizer. With 4 branch configurations, 5 iteration levels, and 18 angle options (between 0 and 90 degrees), there were 360 distinct combinations. To manage this, I built an interactive module that lets readers dynamically select and view any combination.
In[]:=
imageStore=CloudGet["https://www.wolframcloud.com/obj/aditamitkumar/LSystem/imageStore.wl"];Manipulate[Module[{img=Check[Import[imageStore[branches][iterations][angle]],$Failed]},If[ImageQ[img],img,Style["Image not available",Red]]],{{branches,2},{2,3,5,7}},{{iterations,1},Range[1,5]},{{angle,45},Range[0,85,5]},SaveDefinitions->True]
Out[]=
Convex Hull Mesh
Convex Hull Mesh
Generate tree crown mesh:
Randomization of Hull
Randomization of Hull
However, I noticed that the resulting polygon appeared too geometric and rigid, lacking the organic irregularity seen in natural trees. In reality, a tree’s crown is not defined solely by the endpoints of its main branches, but also by the irregular layering of leaves, twigs, and smaller offshoots that contribute to its overall shape. To simulate this, I introduced randomness by applying small, random displacements to the midpoints of the convex hull edges. This helped break the symmetry and made the crown appear more irregular, and lifelike.
Randomize midpoints between endpoints of ConvexHullMesh:
Analysis of Convex Hull Mesh
Analysis of Convex Hull Mesh
Using a constant branching angle, height increment, and number of iterations, I observed a surprising result: the 2-branch trees consistently produced a wider and taller spread than their 3-branch counterparts, resulting in a larger convex hull area.
This can be attributed to the 2-branch system dedicating its growth entirely to lateral expansion (left and right), whereas the 3-branch system splits its growth between vertical and radial directions, producing a more compact structure
The figure below visualizes this difference, with an overlay of convex hulls for both trees. The 2-branch tree (blue) clearly demonstrates a broader canopy compared to the 3-branch tree (red), despite having identical growth parameters.
This can be attributed to the 2-branch system dedicating its growth entirely to lateral expansion (left and right), whereas the 3-branch system splits its growth between vertical and radial directions, producing a more compact structure
The figure below visualizes this difference, with an overlay of convex hulls for both trees. The 2-branch tree (blue) clearly demonstrates a broader canopy compared to the 3-branch tree (red), despite having identical growth parameters.
Stochastic 2D Trees
Stochastic 2D Trees
Randomize branch length and angle for stochastic generation:
If the move length is set to a negative number or left undefined, the function assigns each branch a random length between 0.5 and 1.5. For the angle parameter, providing a list causes the function to select a random angle within that range for each branch, whereas a single numeric value applies a fixed, deterministic angle throughout.
Use of stochastic 2D tree generation:
Convex Hull Mesh for Stochastic 2D Tree
Convex Hull Mesh for Stochastic 2D Tree
After generating stochastic 2D trees, whose randomness produced more natural, asymmetrical forms, I wanted to compare their crown structures using convex hull meshes. This allowed me to quantify how introducing stochasticity influences measurable properties like spread and enclosed area.
Under Wind Conditions
Under Wind Conditions
Inspired by the asymmetric shapes observed in real trees influenced by environmental factors like wind, I extended the stochastic 2D tree model to simulate wind effects. By independently varying the branching angles on the left and right sides of the tree, this approach enables fine-grained control over the directional bias of growth. The two angle inputs specify distinct ranges for each side, producing tree structures that visually reflect wind-driven deformation and asymmetry under varying conditions.
Define a function for wind generation:
Create 2D L-System Tree under wind conditions:
I then generated animations simulating tree movement under wind conditions. This was achieved by dynamically adjusting the ranges of the two branching angles, incrementally increasing one side while decreasing the other, to mimic the directional force of the wind. To avoid mechanical or overly uniform motion, each angle at every frame is randomly selected within its range, introducing natural jitter and variability reminiscent of real-life tree swaying.
Create animated images using WindGenerator function:
3D L-System Trees
3D L-System Trees
To generate more realistic branching structures, I extended the conventional 2D L-system to a 3D space using orientation while following a similar turtle-graphics based model. The result is a recursive generator for 3D tree structures, based on an L-system that controls both movement and spatial orientation.
Function
Function
The "W", "A", "S", "D", "E", "Q" commands extend the current branch by translating the turtle's position, storing each visited point.
◼
W → Move Forward
◼
A → Move Left
◼
S → Move Backward
◼
D → Move Right
◼
E → Move Up
◼
Q → Move Down
◼
Y → Yaw (Left/Right rotation of branch)
◼
P → Pitch (Up/Down rotation of branch)
◼
R → Roll (Clockwise/Counterclockwise rotation of branch)
◼
< → Open New Branch
◼
> → Close Branch
◼
+ → Rotate the orientation in the counterclockwise direction (Placed before Y,P and R)
◼
- → Rotate the orientation in the negative direction (Placed before Y,P and R)
Define Function to generate 3D L-System Trees:
When a branch start symbol (" < ") is encountered, the current position and orientation are pushed onto a stack, allowing the turtle to return to this state after drawing a child branch The corresponding branch end symbol (" > ") pops the state off the stack, restoring the previous position and orientation, and continuing the main branch from there.
Instead of relying on 2D turns and angles, this function defines the turtle's orientation using a full 3*3 bearing matrix.
Each segment of continuous movement is stored in a sublist, resulting in an overall nested list structure for all branches.
Branches
Branches
2 Branch 3D L-System Tree
2 Branch 3D L-System Tree
Branch “W” generates two rotated branches with < and > around yaw and pitch axes. The added R, P, and E movements create vertical and twisting 3D growth with 2 branches.
Define L-System rule and generate 2 branch 3D L-System tree:
3 Branch 3D L-System Tree
3 Branch 3D L-System Tree
Each branch W produces three branches in different rotated directions inside” <...> “. The interleaved X, pitch, and yaw shifts create spatial spread.
Define L-System rule and generate 3 branch 3D L-System tree:
4 Branch 3D L-System Tree
4 Branch 3D L-System Tree
Each branch X creates four diverging branches with nested pitch, yaw, and roll adjustments.
Define L-System rule and generate 3 branch 3D L-System tree:
Convex Hull Mesh
Convex Hull Mesh
Generate ConvexHullMesh of 3D tree and calculate volume:
Stochastic 3D Trees
Stochastic 3D Trees
To introduce natural irregularities into 3D tree structures, I extended the deterministic L-SystemTree3D into a stochastic version that supports randomized branching angles in the three rotational dimensions of yaw, pitch, and roll
Each time a rotation character is encountered in the L-system string, the function checks whether the corresponding angle input is a list or a single value. If a list is given, a random angle is sampled from that range for each rotation event, introducing asymmetry and variation in every branch. If a single value is provided, the system behaves deterministically.
Each time a rotation character is encountered in the L-system string, the function checks whether the corresponding angle input is a list or a single value. If a list is given, a random angle is sampled from that range for each rotation event, introducing asymmetry and variation in every branch. If a single value is provided, the system behaves deterministically.
Randomize Yaw, Pitch and Roll Angles based on list and integer inputs:
Generate ConvexHullMesh of stochastic 3D tree and calculate volume :
Conclusion
Conclusion
Limitations:
Limitations:
◼
Convex hulls can overestimate the canopy area or volume, especially in sparse or uneven trees.
◼
All segments grow in straight lines. Real trees have curved branches due to gravity, light-following behavior, or wind stress.
◼
All branches are modeled with the same thickness, ignoring natural tapering or branch aging.
Future Direction:
Future Direction:
◼
Add logic for dynamic branch thickness based on depth in the tree or rule-based aging, mimicking natural tapering from trunk to tip.
◼
Introduce curvature by chaining smaller rotated segments or using Bézier-like approximations to simulate gravity, wind influence, or phototropism.
◼
Use cellular automata to algorithmically generate or evolve new L-system rule sets.
◼
Apply physical constraints such as wind drag, self-weight drooping, or collision avoidance to create structurally stable and dynamic models.
Fun Stuff
Fun Stuff
Realistic Trees
Realistic Trees
Fantasy Trees
Fantasy Trees
Interesting 2D Patterns
Interesting 2D Patterns
Interesting 3D Trees
Interesting 3D Trees
Acknowledgements
Acknowledgements
I would like to sincerely thank my mentor, Mark Greenberg, for his consistent guidance and encouragement throughout this project. I’m also grateful to the WSRP directors for organizing this opportunity, and to Stephen Wolfram for helping brainstorm and shape the initial idea that inspired this work.
References
References
Prusinkiewicz, P., Hanan, J., Lindenmayer Systems, Fractal, and Plants. Springer-Verlag, 1989.
Prusinkiewicz, P., Lindenmayer, A., The Algorithmic Beauty of Plants. Springer-Verlag, 1990.
Li, A., Muppala, A., Kagan, D., & Hammock, D. (2024, January 2). [WELP23] Generating Plant Structures with 3D Lindenmayer-Systems - Online Technical Discussion Groups—Wolfram Community. Retrieved July 4, 2025, from https://community.wolfram.com/groups/-/m/t/3094962
Soares Germano, R. (2021, June 21). LSystem | Wolfram Function Repository. Retrieved June 30, 2025, from https://resources.wolframcloud.com/FunctionRepository/resources/LSystem/
Borke, P. (1991, July). L-System User Notes. Retrieved July 2, 2025, from https://paulbourke.net/fractals/lsys/
Code
Code
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Exploring branching Lindenmayer systems in 2D and 3D
by Adit Amit Kumar
Wolfram Community, STAFF PICKS, July 10, 2025
https://community.wolfram.com/groups/-/m/t/3497369
by Adit Amit Kumar
Wolfram Community, STAFF PICKS, July 10, 2025
https://community.wolfram.com/groups/-/m/t/3497369
