02_user_tutorials:tutorials:architecture-model
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| 02_user_tutorials:tutorials:architecture-model [2025/01/24 12:01] – ↷ Page moved from tutorials:architecture-model to 02_user_tutorials:tutorials:architecture-model gaetan | 02_user_tutorials:tutorials:architecture-model [2025/01/24 13:13] (current) – removed tim2 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Growth models step by step ====== | ||
| - | In this tutorial we will create a growth model for a crown architecture. The model considers only the branch structure, without leaves, to provide an easy entry point. It may be helpful to understand the basic RGG code structure first, a tutorial is provided [[tutorials: | ||
| - | |||
| - | The model is based on an annual scale, meaning that each run of the growth function simulates one year of growth. This way of simulating a tree in GroIMP is only one of many, and this tutorial focuses on understanding the development. | ||
| - | ===== Organs ===== | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | As mentioned above, the model only considers the branching structure. Therefore it needs only two organs, shoots and buds. | ||
| - | ==== Shoots ==== | ||
| - | |||
| - | In this tutorial, a shoot is always an annual shoot, i.e. the part of a branch that has grown in one year. | ||
| - | We do not take into account the bending of a shoot, so we can describe a shoot as a cylinder. | ||
| - | |||
| - | In GroIMP, our shoot will therefore be a module that extends the turtle command F, which draws a cylinder. | ||
| - | <code java> | ||
| - | module Shoot extends F; | ||
| - | </ | ||
| - | |||
| - | ==== Buds ==== | ||
| - | |||
| - | Each bud considered in this tutorial will generate a shoot, as the other organs that emerge from buds are not considered in the model. | ||
| - | |||
| - | In our GroIMP model, a bud is represented by a small sphere. This means that our bud module extends the sphere object with a parameter for its diameter. | ||
| - | |||
| - | <code java> | ||
| - | module Bud extends Sphere(0.1); | ||
| - | </ | ||
| - | |||
| - | ===== The initial condition ===== | ||
| - | |||
| - | In this model we assume that the simulation starts with a bud. Of course in reality it would start with a seed, but for now we will keep it simple. | ||
| - | |||
| - | As described in the code structure tutorial, the initial state of the simulation is described in the init function. In this case we replace the axiom of our model with a bud. | ||
| - | <code java> | ||
| - | protected void init () | ||
| - | [ | ||
| - | Axiom ==> Bud; | ||
| - | ] | ||
| - | </ | ||
| - | |||
| - | |||
| - | ===== Apical growth ===== | ||
| - | {{ : | ||
| - | |||
| - | Looking at our two organs, we can define our very first rule: //a bud becomes a shoot//, or more precisely //every bud becomes a shoot// | ||
| - | Writing this in an rewriting rule is quite straightforward:'' | ||
| - | |||
| - | |||
| - | |||
| - | This means that our rule has to be a bit more complex, not just for fun, but to keep up with real plant growth.{{ : | ||
| - | So our rule is really //every bud becomes a shoot and a new bud//. | ||
| - | |||
| - | As an XL query this can be described as '' | ||
| - | |||
| - | <code java> | ||
| - | public void grow () | ||
| - | [ | ||
| - | Bud ==>Shoot Bud; | ||
| - | ] | ||
| - | </ | ||
| - | Applying our new rule three times would always replace the bud with a new shoot and a bud, leaving the old shoots underneath the bud untouched. | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | ===== Parameters ===== | ||
| - | With our newly created model we can now create a chain of shoots step by step, basically a branch 8-) . | ||
| - | However, the growth of our model is completely linear and therefore quite unnatural. Even for a very simple model we would like to add some decrease in the length of the shoots over time, as we know it from most trees. So we would like the behaviour shown in the figure below: | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | Formally, we want our bud to produce a shoot that is shorter than the shoot below it. This leads to two problems: firstly, how can we define the length of the shoot, and secondly, how can the bud know this length? | ||
| - | A first step brings us back to our organs. A shoot is no longer just a cylinder, it is now a cylinder of a certain length. In GroIMP we describe this as follows: | ||
| - | <code java> | ||
| - | | ||
| - | </ | ||
| - | This describes that a Shoot can handle a float parameter and also that this parameter is passed to the turtle command F as a length. This would allow us to do XL queries like : '' | ||
| - | <code java> | ||
| - | module Bud(float len) extends Sphere(0.1); | ||
| - | </ | ||
| - | This parameter is not used in the bud, it is just stored as knowledge (a variable). | ||
| - | |||
| - | Assuming that the length of all shoots is still 1, the initial rule would be | ||
| - | '' | ||
| - | |||
| - | and our growth rule | ||
| - | |||
| - | '' | ||
| - | |||
| - | In addition, we can use the parameter of the bud as information for the rule: | ||
| - | |||
| - | '' | ||
| - | |||
| - | This means that each bud in our model is now replaced by a shoot the length of that bud. And the same for the new bud. Finally, we can simply reduce the size for the next generation: | ||
| - | |||
| - | '' | ||
| - | This means that if the initial (yellow) bud has a length parameter of 1, the yellow shoot will be of size 1, but the red bud will have a length parameter of 0.8. So in the next step the red shoot will be of size 0.8 and the green bud will have a length parameter of 0.64... | ||
| - | |||
| - | ===== Lateral growth ===== | ||
| - | |||
| - | {{ : | ||
| - | Although our little model is improving, it can still only grow in one direction, which is not typical for a tree. Therefore, we will now add new shoots to the side of our main branch (trunk). The picture on the right shows what we would like to see after two stages of growth. This branches on the side are called lateral. | ||
| - | |||
| - | {{: | ||
| - | Knowing that our first rule is to turn a bud into a shoot and a bud, we can estimate what the first step towards the branched tree would have looked like. This can be seen in the picture on the left. | ||
| - | |||
| - | This brings us to the task of updating our rule. We now want to //replace a bud with a shoot, a bud at the top and two buds at the sides// | ||
| - | |||
| - | |||
| - | ==== Turtle Geometry ==== | ||
| - | |||
| - | For this new rule we need to look at how GroIMP interprets the results of our rules. | ||
| - | |||
| - | This chain of cylinders and bud is stored in GroIMP in a graph, the project graph. This graph contains almost all information about the project and defines the core of a GroIMP simulation. It is also the basis for the visualisation of our model. As we can see in the left image below, each shoot in the graph is drawn as a cylinder in the 3D scene. The placement of these objects is based on the concept of turtle geometry. We can imagine that a " | ||
| - | |||
| - | |{{: | ||
| - | | Left: Our apical shoot as a drawn image, a GroIMP 2d Graph and the GroIMP visualization, | ||
| - | GroIMP comes with a set of commands to manipulate this turtle by rotating, scaling, moving or chaining default values for color and size. (The most important ones can be found here: [[01_user_documentation: | ||
| - | |||
| - | |||
| - | === A first lateral bud === | ||
| - | |||
| - | {{: | ||
| - | |||
| - | To get a feel for this turtle geometry, we will create a rule that turns the bud into a shoot with a bud on the right side. First we need the shoot and then we add the side bud. Knowing that the turtle will be at the end of the shoot after we draw it means that we have to move back from that position. So we can use the move command: '' | ||
| - | |||
| - | Assuming our shoot has a length of $l$, the turtle will move l up with '' | ||
| - | |||
| - | You can **rotate** the turtle along the three axes x, y and z. We can see an example of the rotation tool on the right with the possible rotations in colors: x=red, y=blue and z=green. In the turtle geometry we can rotate these axes with the commands '' | ||
| - | |||
| - | For our little shoot with the apical bud, this means that we have to rotate it on the y-axis (up, if the branch would lie on the side). Therefore we need the RU command and the following rule: | ||
| - | |||
| - | '' | ||
| - | |||
| - | |||
| - | which, after 3 iterations, produces the " | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | |||
| - | ==== Growing in several directions ==== | ||
| - | |||
| - | We already have two possible rules to create our little plant, we can either grow upwards or to the right. In the next step we want to do both in one rule. Doing this with a turtle moving back and forth would be very hard (sooner or later impossible). | ||
| - | |||
| - | In most L-Systems, and also in GroIMP, this is solved by using a stack of turtle states (the current position, rotation, scale color, etc.). | ||
| - | |||
| - | " | ||
| - | |||
| - | '' | ||
| - | The order of the elements (why we go back before adding the apical bud) becomes clear if we imagine that we apply the rule a second time. In this case, we want the second shoot to be added after the detour and not before (see the graphic below), otherwise the lateral shoot would be moved up with the new shoot. | ||
| - | | ||
| - | In GroIMP' | ||
| - | |||
| - | |||
| - | {{ : | ||
| - | |||
| - | |||
| - | As mentioned above, the turtle state is stored in a stack, so we can move multiple turtle stacks into it. | ||
| - | In our case, this allows us to add some more lateral buds around the shoot (rotated around the head axes): | ||
| - | |||
| - | < | ||
| - | Bud(x) ==> Shoot(x) [ | ||
| - | | ||
| - | RU(30) Bud(x*0.8) | ||
| - | ] RH(120) [ | ||
| - | RU(30) Bud(x*0.8) | ||
| - | ] RH(120)[ | ||
| - | RU(30) Bud(x*0.8) | ||
| - | ] | ||
| - | ]Bud(x*0.8); | ||
| - | </ | ||
| - | |||
| - | This gives us a nice little plant-like structure: | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | You can now play around with the values to change the shape of the tree, e.g. make the side branches shorter (x*0.5 instead of x*.0.8) or change the rotation angels etc. | ||
| - | ===== Branching orders ===== | ||
| - | |||
| - | |||
| - | {{ : | ||
| - | |||
| - | If we look at trees, we can see that most of them have different growth behavior on the trunk and on the branches. To simulate this, we will use the concept of branching order. In this concept, the branches of a tree are separated into orders based on their parent. We define the trunk as order 0, and then each side branch on the trunk is order 1, and each side branch on order 1 is order 2, and so on. This can be seen in the image to the right. | ||
| - | |||
| - | We, like many other modelers before us, will use this concept to give our tree more structure by defining different growth rules for the different orders. | ||
| - | * A bud on the trunk (of order 0) creates a shoot, a new apical bud of order 0, and three lateral buds of order 1 around it. | ||
| - | * A bud of order 1 creates a shoot, a new apical bud of order 1, and two lateral buds of order 2 to the left and right. | ||
| - | * A bud of order 2 creates a shoot and a new bud of order 2. | ||
| - | |||
| - | To use these rules, we first need to know the branching order for each bud. To do this, we need to add an additional parameter to the bud module, as shown below: | ||
| - | <code java> | ||
| - | | ||
| - | </ | ||
| - | |||
| - | And now we learn a new trick, because on the left side of an XL rule you can also specify which value a parameter of the selected node should have: '' | ||
| - | <code java> | ||
| - | |||
| - | Bud(0,x) ==> Shoot(x) [ | ||
| - | | ||
| - | RU(80) Bud(1, | ||
| - | ] RH(120) [ | ||
| - | RU(80) Bud(1, | ||
| - | ] RH(120)[ | ||
| - | RU(80) Bud(1, | ||
| - | ] | ||
| - | ]Bud(0,x); | ||
| - | |||
| - | </ | ||
| - | We now replace only the buds of order 0 (the stem) and give the new buds the correct orders, the lateral buds get order 1 and the apical bud gets 0. | ||
| - | |||
| - | For the first-order branches, the new rule is as follows, with two buds rotated to the left and right. | ||
| - | <code java> | ||
| - | Bud(1, | ||
| - | | ||
| - | [ | ||
| - | RL(70) Bud(2, | ||
| - | ] | ||
| - | [ | ||
| - | RL(-70) Bud(2, | ||
| - | ] | ||
| - | ]Bud(1, | ||
| - | </ | ||
| - | |||
| - | Finally, the second order is just as we have known it from the beginning. | ||
| - | <code java> | ||
| - | | ||
| - | </ | ||
| - | |||
| - | These three rules result in a pretty nice looking structure. (Don't be confused, I resized the radius of the buds a bit) | ||
| - | {{ : | ||
| - | ===== Diameter ===== | ||
| - | |||
| - | Now, in the last real step of this tutorial, we want to look at the diameters of our little tree. | ||
| - | In the F class that our shoot extends, the diameter can be given as a second parameter: '' | ||
| - | <code java> | ||
| - | | ||
| - | </ | ||
| - | |||
| - | To define this value in our rules, we will use a very simple estimation. Let us assume that the ratio between the length of a shoot and its diameter is 10:1. This means that in all our rules we can simply change the Shoots to '' | ||
| - | |||
| - | Even though this gives our tree a nicer initial shape, there is something else we want to do with the diameter: secondary thickness growth. | ||
| - | |||
| - | <code java> | ||
| - | | ||
| - | </ | ||
| - | |||
| - | |||
| - | With the diameter, our tree now looks like this: | ||
| - | {{ : | ||
| - | |||
| - | |||
| - | ===== Final ===== | ||
| - | |||
| - | That is basically it for this tutorial. Below you will find the code for this little tree. Now you can start playing around with it, adding more parameters and rotations to suit your needs. | ||
| - | <code java> | ||
| - | |||
| - | | ||
| - | | ||
| - | |||
| - | | ||
| - | Axiom ==> Bud(0,1); | ||
| - | ] | ||
| - | |||
| - | | ||
| - | |||
| - | Bud(0,x) ==> Shoot(x, | ||
| - | | ||
| - | RU(80) Bud(1, | ||
| - | ] RH(120) [ | ||
| - | RU(80) Bud(1, | ||
| - | ] RH(120)[ | ||
| - | RU(80) Bud(1, | ||
| - | ] | ||
| - | ]Bud(0, | ||
| - | | ||
| - | M(-0.5*x) | ||
| - | | ||
| - | RL(70) Bud(2, | ||
| - | | ||
| - | | ||
| - | RL(-70) Bud(2, | ||
| - | | ||
| - | | ||
| - | |||
| - | | ||
| - | |||
| - | |||
| - | | ||
| - | ] | ||
| - | </ | ||
| - | |||
02_user_tutorials/tutorials/architecture-model.1737716500.txt.gz · Last modified: 2025/01/24 12:01 by gaetan
