====== A simple tomato plant model ======
In this tutorial we will create a simple model of architecture and development of a tomato plant.
===== Organs =====
module Organ(super.length) extends M(length);
module Apex extends Organ;
module Internode extends Organ;
module Leaf extends Organ;
module Leaflet extends Organ;
module Flower extends Organ;
==== Parameters for organ geometry ====
static double PHYLLOTAXIS_ANGLE = 137.51;
static double LEAF_ANGLE = 60;
static double LEAF_LENGTH = 0.40;
static double PETIOLE_WIDTH = 0.01;
static double INTERNODE_LENGTH = 0.08;
static double INTERNODE_WIDTH = 0.02;
static int NB_VEG_PHYTOMERS = 8;
==== Specifying organ geometry ====
module Apex extends Organ
==>
Sphere(0.01).(setShader(RED))
;
module Internode extends Organ
{
double width;
{
length = INTERNODE_LENGTH;
width = INTERNODE_WIDTH;
}
}
==>
Cylinder(length, width/2).(setShader(YELLOW))
;
module Leaf extends Organ
{
double width;
double angle;
double petioleLength;
double petioleWidth;
{
length = LEAF_LENGTH;
width = 0.5*LEAF_LENGTH;
angle = LEAF_ANGLE;
petioleLength = 0.2*LEAF_LENGTH;
petioleWidth = PETIOLE_WIDTH;
}
}
==>
RL(angle)
Cylinder(petioleLength, petioleWidth/2).(setShader(GREEN))
Parallelogram(length-petioleLength, width)
;
module Truss extends Organ
==>
RL(TRUSS_ANGLE) RH(90)
for (int i:1:NB_FLOWERS) (
Cylinder(0.02,0.001).(setShader(YELLOW))
[
if(i%2==0) (
RH(90)
) else (
RH(-90)
)
RU(60)
Cylinder(0.02,0.001).(setShader(BLUE))
Sphere(0.02).(setShader(RED))
]
RU(-20)
)
;
===== The initial condition =====
protected void init()
[
Axiom ==> Apex;
]
===== Rewriting rules =====
First, we specify rewriting rules for vegetative development of the primary shoot in tomato.
public void run()
[
a:Apex ==>
Internode
[Leaf]
RH(PHYLLOTAXIS_ANGLE)
a
;
]
After a certain number of phytomers (internodes with leaves), specified by a parameter NB_VEG_PHYTOMERS, primary shoot will change into sympodial shoot. For this, a repetitive pattern with 3 leaves and 1 truss with fruits is typical for many (high-wire) tomato cultivars.
public void run()
[
a:Apex, (a[rank] < NB_VEG_PHYTOMERS) ==>
Internode
[Leaf]
RH(PHYLLOTAXIS_ANGLE)
a
{a[rank]++;}
;
a:Apex, (a[rank] >= NB_VEG_PHYTOMERS) ==>
Internode
if ((a[rank] - NB_VEG_PHYTOMERS) % 4 == 1) (
[Truss]
) else (
[Leaf]
)
RH(PHYLLOTAXIS_ANGLE)
a
{a[rank]++;}
;
]
===== Improving leaf structure =====
===== Introducing timing of organ appearance based on thermal time =====