Fractal Trees – Basic L-System- Example 9.4
Another very useful application for fractal processes is to create 3D vegetation for your models. There are several very good commercial products which use algorithms to create plants, which combine mathematical understanding with botanical knowledge to make tree and plant generators. Two popular products that I have a little experience with are Xfrog and Laubwerk, both initially developed by German programmers. While the goal of this post is not to get you to recreate their software, understanding some of the basic principles can help you use either one more intelligently (if you want or need high quality plants for renderings), but can also serve as an inspiration for potential design applications which go beyond rendering and representation. Also, creating your own simple tree generator, combined with a smart use of a random seeds can allow you to make basic ‘stick’ models of plants that don’t look repetitive and which can give an impression of vegetation quality and massing without being too photo-realistic.
A core family of algorithms in these plant generators are ‘L-systems’, or Lindenmayer systems. You can read about these to get a general sense of the mathematical theory but I find the best way to start to understand them is to do a few yourself. A useful plugin for Grasshopper that works with L-systems is one called Rabbit by Morphocode, but I will show you 4 simple L-systems that can be easily developed without Rabbit using only Grasshopper and Anemone, and from there maybe you can experiment with your own. Another useful source for starting to develop your own L-systems is the book “The Algorithmic Beauty of Plants” which you can download for free via PDF, a product of the research Institute Algorithmic Botany at the University of Calgary. Some of my examples are explained in this book in more detail.
Like the fractal systems we looked at previously, L systems have a set of production rules, which are repeated through a few recursions or generations. Each generation starts drawing a structure at a starting point, and draws lines at defined angles and lengths. Each subsequent generation draws a similar structure at new starting points that were defined in the previous generation.
Probably the simplest L-system is One where you take a point, and draw two lines, one at a positive vector angle, and one negative (the angle is a variable). The length of the line is proportionally reduced in each generation.
With these production rules, after each generation the number of Lines doubles. By varying the angle of branching and the proportion of reduction for each generation, though, the formal expression of the production rules can be quite different. I coded these production rules in an Anemone loop in Grasshopper, and after a fixed number of generations (much more than 7 or 8 generations will be overkill!) it draws pipes along each line with the radius of the Pipe based on the overall length of the line. Script image to follow a bit later…
The above image shows how one of these systems can radically change with various angles ranging between 15° and 90°. As you can see, the angles much above maybe 30° don’t look like real plants but between 15° and 30° they can look surprisingly life-like, especially considering the sheer simplicity of the system.
The script should be easy to develop if you have been following along with the previous exercises and if you’re a somewhat capable user of Grasshopper. The ‘L’ system is developed in the blue part of the script.
Various plants have self-similar, repeating logics that define their structure. If you have studied plant botany and tree identification, you will know some species have branches that alternate, some where two branches always come from the same spot, etc. Understanding potential structures can allow you to modify the system.
In the image above, I show three variants to my initial script. In the first, Instead of drawing two lines to loop, I draw three, one going straight. The other two variations have slightly more complex branching structures, but should be easy to code if you understand the system.
Trees in nature also follow basic rules, with variation in growth created by factors such as soil composition, sunlight, adjacencies, and genetic chance. Once you develop a basic process, you can find ways to introduce variation into the system. Here it is done very simply, just by varying the length of the initial line. You’ll notice the overall structure of each tree is exactly the same though…only the scale is different. More complex variation can be introduced with things like random number generators. In a future example, I will show the creation of a 3D tree using a random number generator that gives a possible range of branching angles, plus a system for rotating the branches in the 3rd dimension. The results of my initial test are shown in the image below, but you’ll have to wait for the explanation…or try and figure it out yourself! 🙂 The only hint I will give you is you have to really pay attention to your data structures!
PLEASE PLEASE PLEASE SHOW THE EXAMPLE FOR A 3 DIMENSION BRANCHING TREE!!!! PRETTY PLEASE!!!!!
LikeLike
Hi,
I believe that in the script screenshot the axis for the rotated vectors is Z, not Y.
Please check this, for me it worked with Z unit vector, not Y.
Cheers.
LikeLike
Hi Yafim,
You are correct. As am I. Since I am drawing my trees in the front view (elevation), with the initial line going in the vertical, Z-direction, the rotation axis is the Y-axis, but if you draw your initial line in plan view, you would be correct in using “Z”. Maybe I should add a note to that effect. but thanks for your note!
LikeLike
Hi,
Another question if you may. For some reason I did this a few days ago successfully but the code disappeared and I am stuck on the same point. I am trying to use variable pipe instead of pipe, and to relate the length of lines to thickness of pipe. Let me know where to send a photo of the situation so you can see.
In any case, I have 4 lines, with 4 lengths, and I divide them to get 4 numbers. I make the VarPipe parameters the lengths, and the radii the numbers. For some reason it just doesn’t produce anything.
Thanks.
LikeLike
Hi Yafim,
I tried this based on your recommendation, and the variable pipe definitely improves the script! The basic idea would be you have two parameters, one at the start, and one at the end of the line (0 and 1). The first radius is proportional to the length of the segment, the second is proportional to the length of the segment times the initial scaling factor. You also need to get your data structure right (best results with grafted values).
I can send a picture of my solution if you’d like, or you can send me yours. josclag AT hotmail DOT com
LikeLike
I was Inspired by the pictures of the 3d tree you posted, i’m new to grasshopper and self taught. i tried having an attempt at replicating the 3rd dimension vector by adding another vectore rotation component on the Z axis, which didn’t work. I’m curious as to to how you managed to do that. Any insight would be valued, thanks. Grace
LikeLike
Hello, I was inspired by your 3d tree and i decided to give it a go by rotating the resultant vector from the 2d version one more time on the Z axis. I am new to grasshopper and self taught. and while i enjoyed the challenge, it would be nice to see how far off i was from the actual solution. Any chance you could share it please?
LikeLike
Instead of taking the z or y axes, use the perpendicular frame component at the end parameter of the curve. Then, deconstruct the plane and use the corresponding z or y axes as rotational axes.
LikeLike