Guida Botanica Computazionale: come creare un albero

  • Autore discussione Utente cancellato 210785
  • Data d'inizio
Stato
Discussione chiusa ad ulteriori risposte.
U

Utente cancellato 210785

Ultima modifica da un moderatore:
Botanica computazionale: come creare un albero

In questi giorni ho avuto la necessita' di studiare il modo di realizzare
degli alberi aventi specifiche caratteristiche statistiche e ottiche.

Ora, senza andare troppo nel dettaglio, il tutto si puo' riassumere in questo modo.

Esistono essenzialmente due modelli matematici alla base della progettazione di
alberi dalla forma realistica:

1) quello basato sull'articolo di Jason Webe e Joseph Penn

https://www.cs.duke.edu/courses/fall02/cps124/resources/p119-weber.pdf

2) quello basato sul modello frattale di Lindenmayer, detto L-system

http://en.wikipedia.org/wiki/L-system
http://algorithmicbotany.org/papers/#abop

Molti software, sia open source che a pagamento, sono basati sul primo sistema. Ad esempio

ngPlant: http://ngplant.sourceforge.net/
arbaro: http://arbaro.sourceforge.net/
Xfrog: http://xfrog.com/
OnixGarden: http://www.onyxtree.com/suite.html
ecc

Invece non ne ho trovati molti che utilizzano il secondo modello:

Fractal Grower: http://www.cs.unm.edu/~joel/PaperFoldingFractal/paper.html
L-Studio: http://algorithmicbotany.org/lstudio/whatis.html
L-Py: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3362793/
http://openalea.gforge.inria.fr/wiki/doku.php?id=packages:vplants:lpy:main

Dal punto di vista implementativo, il modello basato sul L-system risulta il piu' semplice:
fondamentalmente puo' essere implementato utilizzando la Turtle Graphics.

http://en.wikipedia.org/wiki/Turtle_graphics

La Turtle Graphics o Grafica della Tartaruga e' un modello di grafica che e'
stato inventato nel 1960 per il linguaggio Logo (http://en.wikipedia.org/wiki/Logo_(programming_language))
per avvicinare i bambini alla programmazione.

Ma attenzione, nella sua semplicita' la Grafica della Tartaruga si appoggia
ad un tipo di geometria tutt'altro che banale, e cioe' alla geometria differenziale,
settore estremamente vasto e complesso della geometria, usato sopprattutto in
fisica e astronomica.

Ovviamente non serve conoscere la geometria differenziale per usare la tartarughina
per disegnare, ma un paio di concetti si.

Innazi tutto partiamo da una considerazione fondamentale: il nostro albero e' un oggetto
tridimensionale, quindi la tartarughina dovra' muoversi nello spazio, e non nel piano, come
nella maggior parte delle implementazioni delle librerie per questo tipo di grafica.

La seconda considerazione e' la seguente: la Grafica della Tartaruga consiste
nel comandare la tartarughina come un robot, dicendogli:

- vai avanti/indietro
- gira a destra/sinistra
- ...

benche' queste informazioni siano relative alla posizione corrente della tartaruga, il grafico
generato, ovviamante, richiede un sistema di coordinate globale.

Quindi la tartarughina righiede un certo numero di informazioni. Vediamo quali:

1) ovviamente la posizione,
2) la direzione di marcia
3) poiche' siamo nello spazio, serve sapere anche quale e' la direzione alto
4) per comodita', e per semplificare l'implementazione, anche quale e' la direzione destra

Queste sono rappresentate mediante dei vettori di 3 elementi: (x,y,z).

Ora serve comandare la tartarughina.
Se fossimo sul piano, ci sono fondamentalmente due operazioni possibili:

- vai avanti/indietro
- gira a destra/a sinistra

Poiche' siamo nello spazio, mentre il comando vai avanti/indietro indietro ha
abbastanza senso, il comando gira a destra/a sinistra non basta.

Infatti, le rotazioni, nello spazio, sono 3, ben conoscite da chi sa qualcosa di aeronautica
o va a vela:

1) rollio (roll): e' il movimento rotatorio lungo l'asse avanti/indietro
(quando la barca si muove dopo che un'altra barca gli e' passata a fianco)
2) beccheggio (pitch): e' il movimento rotatorio lungo l'asse destra/sinistra
(quando la barca salta sulle onde)
3) imbardata (yaw): e' il movimento rotatorio lungo l'asse alto/basso
(quando una aereo atterra ed ha il vento di fianco)

Ok. A questo punto ci sono abbastanza informazioni per immplementare una primitiva
Grafica della Tartaruga in 3 Dimensioni.

Per comodita' ho usato Python e la libreria VPython, sotto Windows:

Codice:
from __future__ import division
from visual import *

#
# Axes:
#
# X -> right
# Y -> forward
# Z -> up
#
# Rotations:
#
# Y -> roll     (rollio:     rotazione attorno alla direzione di marcia avanti/indietro)
# X -> picth    (beccheggio: rotazione attorno all'asse che indica la direzione destra/sinistra)
# Z -> yaw      (imbardata:  rotazione attorno all'asse che indica la direzione alto/basso)
#

class Turtle3D:
    def __init__(self):
        self.pos = vector(0, 0, 0)
        self.forward = vector(0, 1, 0)
        self.up = vector(0, 0, 1)
        self.right = vector(1, 0, 0)

        self.color = (1, 0, 0)
        self.stack = []

        self.turtle = [
            pyramid(pos=self.pos, axis=self.forward, size=(0.25,0.05,0.05), up=self.up, color=(1,1,0)),
            cylinder(pos=self.pos, axis=0.1*self.up, radius=0.01)
        ]
    #end

    def set_pos(self, p):
        self.pos = p
        self.show()
    #end

    def set_color(self, c):
        self.color = c
    #end

    def translate(self, t):
        tx, ty, tz = t
        tr = tx*self.right + ty*self.forward + tz*self.up
        self.pos = self.pos + tr
        self.show()
    #end

    def advance(self, l):
        dest = self.pos + l*self.forward
        cylinder(pos=self.pos, axis=l*self.forward, radius=0.01, color=self.color)
        self.pos = dest
        self.show()
    #end

    def move(self, l):
        dest = self.pos + l*self.forward
        self.pos = dest
        self.show()
    #end

    def roll(self, angle):
        angle = angle*pi/180
        self.up = self.up.rotate(angle=angle, axis=self.forward)
        self.right = self.right.rotate(angle=angle, axis=self.forward)
        self.show()
    #end

    def pitch(self, angle):
        angle = angle*pi/180
        self.up = self.up.rotate(angle=angle, axis=self.right)
        self.forward = self.forward.rotate(angle=angle,axis=self.right)
        self.show()
    #end

    def yaw(self, angle):
        angle = angle*pi/180
        self.forward = self.forward.rotate(angle=angle, axis=self.up)
        self.right = self.right.rotate(angle=angle, axis=self.up)
        self.show()
    #end

    def save(self):
        self.stack.append((self.pos, self.forward, self.right, self.up))
    #end

    def restore(self):
        l = len(self.stack)-1
        self.pos, self.forward, self.right, self.up = self.stack[l]
        self.stack = self.stack[0:l]
        self.show()
    #end

    def show(self):
        p, c = self.turtle
        p.pos = self.pos
        p.axis = 0.1*self.forward
        p.up = self.up

        c.pos = self.pos
        c.axis = 0.1*self.up
    #end
#end


sw = 1920
sh = 1080
ww = 1440
wh = 900.

d = display(x=(sw-ww)/2, y=(sh-wh)/2, width=ww, height=wh, center=(0, 0, 0), up=(0, 0, 1), forward=(-1.5, -1, -1), range=(5, 5, 5))

#
# scommentare per gli assi X,Y,Z
#
# sphere(radius=0.02, color=(1, 1, 0))
# cylinder(pos=(0, 0, 0), axis=(.3, 0, 0), color=(1, 0, 0), radius=0.005)
# cylinder(pos=(0, 0, 0), axis=(0, .6, 0), color=(0, 1, 0), radius=0.005)
# cylinder(pos=(0, 0, 0), axis=(0, 0, .9), color=(0, 0, 1), radius=0.005)

E partendo da questo, e' possibile creare il primo banalissimo alberello
(al momento senza folglie ;) ):

Codice:
t = Turtle3D()


def tree(d, l):
    if (d == 0):
        t.save()
        t.advance(l)
        t.restore()
    else:
        l3 = l/2
        t.save()
        t.advance(l-l3)
        t.save()
        t.pitch(30)
        tree(d-1, l3)
        t.restore()
        t.save()
        t.roll(120)
        t.pitch(30)
        tree(d-1, l3)
        t.restore()
        t.save()
        t.roll(240)
        t.pitch(30)
        tree(d-1, l3)
        t.restore()
        t.restore()
    #end
#end


t.pitch(90)
tree(3, 2)


Questo e', ovviamente, solo la punta del'iceberg ( ;) ).

PS: lo so, lo so! Non e' interessante come hackerare la NASA (o meglio, la NSA) o la rete wifi della scuola.
Ma spero che qualcuno lo trovi lo stesso interessante ;)

Tree.png
 
Sono ignorante e non ho capito molto bene (anche perchè molte parole mi risultano sconosciute D: ), ptete farmi un riassuntino senza entrare molto nel dettaglio? (poi vedrò io u_u), però! ho capito che si può fare un bel alberello XD
 
Sono ignorante e non ho capito molto bene (anche perchè molte parole mi risultano sconosciute D: ), ptete farmi un riassuntino senza entrare molto nel dettaglio? (poi vedrò io u_u), però! ho capito che si può fare un bel alberello XD

Ha creato un modello 3d di un albero direttamente da riga di codice.

Anyway a me sembra molto interessante ma allo stesso tempo molto complesso e lungo, con le giuste conoscenze della geometria si possono fare cose pazzesche..
 
  • Mi piace
Reazioni: TheSeeker
Molto interessante, questo è il genere di post di cui parlavo nel descrivere le potenzialità di una sezione matematica in cui poter parlare anche di algoritmi e teoria.
Conoscevo già abbastanza dettagliatamente il modello di Weber Penn (perchè viene usato dall'addon sapling di blender per generare gli alberi) ma Lindenmayer lo avevo solo sentito nominare.

p.s.
Iceberg* (a meno che tu non sia tedesco)
 
Ultima modifica da un moderatore:
Avevo letto di utenti che usavano blender, quindi ho supposto che un po' di concetti di computer grafica siano conosciuti.
Se volete delle spiegazioni su parole di cui non conoscete il significato, o approfondimenti su particolari concetti/argomenti, si puo' fare ;).

Ovviamente la parte del codice e' quella meno interessante. Le cose interessanti sono scritte nei pdf linkati. E negli altri articoli raggiungibili attraverso i riferimenti bibliografici (santo Internet ;) )

Se avete altre informazioni al riguardo (ad esempio il plugin di blender!) scrivete, scrivete!!!

Devo imparare ad usare blender, acciderbolina! E sopprattutto a programmarlo!
 
  • Mi piace
Reazioni: TheSeeker
Stato
Discussione chiusa ad ulteriori risposte.