====== 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 =====