In my archeological exploration of old computer files, I came across to another simple but interesting Amiga Basic program that I programmed in 1989. It is named “Foglie”, the Italian name for leaves. It was an attempt to explore some ideas of functional plant morphology modeling. The stimulus comes after the reading of the paper by Karl J. Niklas on issue 213 of Le Science (the Italian edition of the Scientific American magazine ). The article titled “Computer-simulated plant evolution” and was a description of the modeling of plants to study their interaction with the environment. It was a fascinating paper, and still simple and primitive graphics was catching my imagination. Nowadays the field of digital morphology come to an age (just to mention one, Avatar) and we can have an idea of this progress in the level of realism in movies, video games, TV programs. My curiosity an interest has been always caught by the form and shapes of the organism and the structure of leafs nervation was an intriguing pattern very much related to my acquaintance with the fascinating fractals objects, another recurrent topic in the pages of scientific magazines of the period.
At that time, I did also my first upgrade from the “mythical” Commodore VIC 20 to the then rising stars MSX computers (MSX was a standardized home computer architecture popular in the ’80. Different company invested money in this new system, my lovely parents gave me as a gift MSX Philips VG-8010). The superb graphics capability of the MSX basics (an extended version of the Microsoft Basic) compared to the Commodore systems gave me the opportunity to easily dive in programming computer graphics. Among, the various projects, I did program a first version of the program Foglie.
I discovered later that the theoretical morphology of plant and other organisms move in two directions. The so-called symbolic language and the functional approach. The first one was invented by Aristid Lindenmayer and named L-systems in his honor . This approach owes much to the concept of self-similarity and of the programming approach introduced by … in the 70 with the as programming languages PILOT and LOGO . This approach describes the structure of plant in term of self-recurrent strings that encapsulates few simple repetitive commands. On the contrary, the functional approach tries to describe the morphology of the organism with mathematical functions. A typical example is a shape of the seashell (I will cover this argument in detail in another blog) that can be approximated, for example, by rescaling and translating the shell opening along an helico-spiral. My pristine idea to model the shape of leaves in two dimensions was based on a functional approach. I didn’t progress much in this direction since my application was as many other reported in these pages, more a young amateur approach to the scientific research, but I think I got some interesting results. I revisit the idea few years after (1993) when, owning an Amiga 500 (see my previous blog here), I rewrote the program in Amiga Basic adding other ideas for making more realistic the model.
The program generates a leaf shape in two dimensions given a set of parameters. In particular, it requires the number of secondary veins detaching from the central one, the angle of detaching, the number of segments in the secondary veins and the progressive curvature of the segments going form the attachment to the periphery. Once the simplified skeleton was generated the terminal points of the secondary nerves are connected with functions of different convexity to simulate the border of the leaf lamina. The program is very simplistic but the shape resembles quite impressively the shapes of different type of leaves.
I have run the program using FS-UEA Amiga emulator on a MacBook laptop, and, in Figure 1, some results are reported. The copy of the program is also provided in the Appendix if there is some interest to explore the code.
Figure 1: Example of output by the program Foglie.
- K.J Niklas. Computer-simulated plant evolution. Scientific American. 254(3), 78-86, March 1986.
- Prusinkiewicz P, Lindenmayer A. The Algorithmic Beauty of Plants. New York: Springer-Verlag; 1996. A free preprint is also available here.
- Abelson H, DiSessa A.A. Turtle Geometry: The Computer as a Medium for Exploring Mathematics (MIT Press Series in Artificial Intelligence); 1986.
Program in Amiga Basic used to generate the shapes in Figure 1.
'******************************************************************** ' FOGLIE ' ' VERSIONE AMIGA 4/1/1989 ' (adattato da una versione scritta per MSX nel 1986) ' Revisione e correzione: 11/7/1993 ' ' DESCRIZIONE ' Il programma serve a generare delle configurazioni di nervature ' fogliari variando alcuni parametri geometrici. ' ' LISTA DEI PARAMETRI ' ' a=distanza minore tra due nervature sulla nervatura centrale. ' b=distanza maggiore tra due nervature sulla nervatura centrale. ' g=angolo d'innesto (angolo tra la nervatura centrale e quelle ' laterali. ' n=numero di nervature che partono dalla nervatura centrale. ' l=lunghezza segmenti che costituiscono le nervature secondarie. ' c=numero di segmenti di ogni nervatura secondaria. ' fat=inverso del coefficiente per la curvatura delle nervature ' secondarie. ' ' (c) D. Roccatano 1986-1993 '******************************************************************** SCREEN 1,640,256,4,2 WINDOW 2,"FOGLIE",,14,1 RANDOMIZE TIMER DIM nerv(2,1,200) pi=ATN(1)*4 ' Inizializazione parametri a=5 b=9 c=5 g=120 n=10 l=80/c fat=120 ' ' PRINT PARAMETERS ' LOCATE 3,40:PRINT " LISTA DEI PARAMETRI " LOCATE 4,40:PRINT "==========================" LOCATE 5,40:PRINT "DISTANZA MINIMA...........:";a LOCATE 6,40:PRINT "DISTANZA MASSIMA..........:";b LOCATE 7,40:PRINT "ANGOLO D'INNESTO..........:";g LOCATE 8,40:PRINT "NUM. DI SEG.xNERVATURE....:";n LOCATE 9,40:PRINT "LUNGHEZZA DEI SEGMENTI....:";l LOCATE 10,40:PRINT "NUM. DI NERVATURE ........:";c LOCATE 11,40:PRINT "CURVATURA ................:";fat ' Definizione della funzione che descrive il profilo della lamina ' fogliare 'DEF FNlun(nseg)=l DEF FNlun(nseg)=l*SIN(pi*(nseg)/n) 'DEF FNlun(nseg)=l*((n-seg)/n) 'DEF FNlun(nseg)=l*SIN(pi*(nseg)/n)*SIN(pi*(nseg)/n) ' ' Calcola i punti di innesto sulla nervatura centrale delle ' nervature secondarie ' gg=0 x=0 y=0 ciclo1: FOR t=0 TO 2*n STEP 2 k=INT(RND*3) h=INT(RND*2) y=y+b+k nerv(0,1,t)=y nerv(0,0,t)=x y=y+a+h nerv(0,1,t+1)=y nerv(0,0,t+1)=x NEXT t ' ' Calcola il nodo del primo segmento delle nervature secondarie ' nseg =0 ciclo2: FOR t=0 TO 2*(n-1) STEP 2 x1=nerv(0,0,t) y1=nerv(0,1,t) x2=x1+FNlun(nseg)*SIN((g*pi)/180) y2= FNlun(nseg)*COS((g*pi)/180) yk=y2+y1 nerv(1,0,t)=x2 nerv(1,1,t)=yk nerv(1,0,t+1)=-x2 y3=nerv(0,1,t+1) yh=y2+y3 nerv(1,1,t+1)=yh NEXT t IF c=1 GOTO graf ' ' Calcola i nodi degli altri segmenti delle nervature secondarie ' ss=2*n m=2 rr=2*n nseg=0 ciclo3: FOR tt=1 TO c-1 FOR t=ss TO 2*(rr-1) STEP 2 x1=nerv(1,0,t-2*n) y1=nerv(1,1,t-2*n) y2=nerv(1,1,t-2*n+1) FOR z=2 TO m gg=gg+g/fat IF (g-gg) =< 0 THEN gg=gg+g/z:GOTO sub2 NEXT z sub2: q=((g-gg)*pi)/180 x2=x1+FNlun(nseg)*SIN(q) y3= FNlun(nseg)*COS(q) nerv(1,0,t)=x2 nerv(1,1,t)=y1+y3 nerv(1,0,t+1)=-x2 nerv(1,1,t+1)=y2+y3 gg=0 nseg=nseg+1 NEXT t gg=0 nseg=0 ss=2*rr rr=rr+n m=m+1 NEXT tt graf: ' ' Disegna rettangolo di contorno e nervatura centrale ' LINE(5,5)-(250,181),2,bf LINE(127,180)-(nerv(0,0,2*n+1)+128,180-nerv(0,1,2*n+1)),4,b ' ' Disegna primo segmento delle nervature secondarie ' FOR tt=0 TO 2*(n-1) LINE(nerv(0,0,tt)+128,180-nerv( 0,1,tt))-(nerv(1,0,tt)+128,180-nerv(1,1,tt)) LINE(nerv(0,0,tt+1)+128,180-nerv( 0,1,tt+1))-(nerv(1,0,tt+1)+128,180-nerv(1,1,tt+1)) NEXT tt ' ' Disegna altri segmenti delle nervature secondarie ' sub1: ss=2*n rr=2*n FOR t=1 TO c-1 FOR tt=ss TO 2*(rr-1) STEP 2 LINE(nerv(1,0,tt-2*n)+128,180-nerv(1,1,tt-2*n))-(nerv(1,0,tt)+128,180-nerv(1,1,tt)),1 LINE(nerv(1,0,tt-2*n+1)+128,180-nerv(1,1,tt-2*n+1))-(nerv(1,0,tt+1)+128,180-nerv(1,1,tt+1)),1 NEXT tt ss=2*rr rr=rr+n NEXT t ' ' Disegna profilo della lamina ' rr=rr-n ss=2*(rr-n) FOR tt=ss TO 2*(rr-2) STEP 2 LINE(nerv(1,0,tt)+128,180-nerv(1,1,tt))-(nerv(1,0,tt+2)+128,180-nerv(1,1,tt+2)),1 LINE(nerv(1,0,tt+1)+128,180-nerv(1,1,tt+1))-(nerv(1,0,tt+3)+128,180-nerv(1,1,tt+3)),1 NEXT tt tt=tt-2 LINE(nerv(1,0,tt+2)+128,180-nerv(1,1,tt+2))-(nerv(0,0,2*n+1)+128,180-nerv(0,1,2*n+1)),1 LINE(nerv(1,0,tt+3)+128,180-nerv(1,1,tt+3))-(nerv(0,0,2*n+1)+128,180-nerv(0,1,2*n+1)),1 GOTO sub1