Table of Contents

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