Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Como replicar modelo de inflorescência com crescimento simpodial usando L-Systems (Lindenmayer-Systems)?

0 votos
13 visitas
perguntada Set 10 em Programação Computacional por Camilaspinto (6 pontos)  

A figura a ser replicada é a Figura 3.15(a) do livro "The Algorithmic Beauty of Plants" de Przemyslaw Prusinkiewicz e Aristid Lindenmayer (1991).

A imagem será apresentada aqui.

Compartilhe

1 Resposta

0 votos
respondida Set 17 por Camilaspinto (6 pontos)  

Segue breve descrição sobre o L-Systems:
“The central concept of L-systems is that of rewriting. In general, rewriting is a technique for defining complex objects by successively replacing parts of a simple initial object using a set of rewriting rules or productions.” (PL1991)

Para replicação da figura utilizou-se o conceito do L-System por meio de recursão. Definiram-se funções para cada parte da planta que se repete e que é replicada à medida que esta vai crescendo.

Foi utilizada a biblioteca turtle e definida função para desenho da folha:

from turtle import *

def folha(r, s):
    '''
    Desenho da folha
    '''
    circle(r, s) # desenho da folha
    circle(r,-s) # de volta ao eixo

Função para desenho da flor:

def flor():
        '''
        Desenho do círculo que representa a flor
        '''
        rt(90) # posição inicial para desenhar a flor
        fillcolor('black') # definição da cor da flor
        begin_fill() # início do desenho
        circle(5) # desenho do círculo que representa a flor
        end_fill() # fim do desenho

Funções para desenho da inflorescência à esquerda e da inflorescência à direita:

def inflor_esq(n, x, r, s, angle, increment):
    '''
    Desenho inflorescência à esquerda
    n = número de flores 
    x = tamanho do caule que segura a flor
    r = raio para desenho da folha da inflorescência
    s = tamanho da folha da inflorescência
    increment = incremento do ângulo para formação de nova flor
    '''
    seth(150 + angle) # ângulo para desenhar a folha do ramo em espiral
    folha(r, s)
    seth(120 + angle) # ângulo para desenhar o caule de onde sairá a flor
    forward(x) # desenho do caule
    flor()
    seth(120 + angle) # ângulo para retornar ao caule
    backward(2*x/3) # volta para o primeiro terço do caule, onde o processo se repetirá até chegar à última flor

    if n>1:
        inflor_esq(n-1, x, r, s, angle+increment, increment) # recursão
    elif n==1:
        inflor_esq(n-1, (x/2), r, s, angle+increment, increment) # recursão
        return up()
    else:
        return


def inflor_dir(n, x, r, s, angle, increment):
    '''
    Desenho inflorescência à direita
    n = número de flores 
    x = tamanho do caule que segura a flor
    r = raio para desenho da folha da inflorescência
    s = tamanho da folha da inflorescência
    increment = incremento do ângulo para formação de nova flor
    '''
    seth(30 - angle) # ângulo para desenhar a folha do ramo em espiral
    folha(-r, s)
    seth(60 - angle) # ângulo para desenhar o caule de onde sairá a flor
    forward(x) # desenho do caule
    flor()
    seth(60 - angle) # ângulo para retornar ao caule
    backward(2*x/3) # volta para o primeiro terço do caule, onde o processo se repetirá até chegar à última flor

    if n==1:
        inflor_dir(n-1, (x/2), r, s, angle+increment, increment) # recursão
        return up()
    if n>1:
        inflor_dir(n-1, x, r, s, angle+increment, increment) # recursão
    else:
        return

Função para desenho do topo:

def topo(x, r, s):
    seth(150) # ângulo para desenhar a folha da inflorescência do topo
    folha(r, s)
    seth(120) # ângulo para desenhar o caule de onde sairá a flor
    forward(x/2) # desenho do caule
    flor()
    seth(120) # ângulo para retornar ao caule
    backward(x/2) # volta para metade do caule, onde sairá o caule para a flor do topo
    seth(90)
    forward(2*x/3) # desenho do caule da flor do topo
    flor()

Por fim, foi criada função para o desenho da planta com a utilização das funções mencionadas anteriormente:

def planta(n, x, r, s, f):
    '''
    Desenho da planta completa
    n = número de entrenós
    x = tamanho dos entrenós
    r = raio para desenho da folha do caule
    s = tamanho da folha do caule
    '''
    forward(x) # desenho do entrenó

    if n<=1: # considerou-se dois entrenós com folhas nos respectivos nós 
        folha(r, s)
        planta(n+1, x, -r, s, f)
    elif n<=5: # a partir do terceiro nó já aparece inflorescência alternadamente à esquerda e à direita
        posicao = pos()

        if n%2==0:
            inflor_esq(f, 35, r/2, s/2, 0, 30)
            setpos(posicao)
            seth(90)
            down()
            planta(n+1, x, r, s, f-1) # recursão
        else:
            inflor_dir(f, 35, r/2, s/2, 0, 30)
            setpos(posicao)
            seth(90)
            down()
            planta(n+1, x, r, s, f-1) # recursão

    elif n==6: # a inflorescência do topo aparece no sétimo nó
        topo(35, 15, 50)
        return

Na função que desenha a planta, a recursão foi utilizada com n crescente. Quando a função é chamada com n=0, já desenha um entrenó e uma folha e novamente chama a mesma função, agora com n=1.
Com n=1, a função planta desenha mais um entrenó e uma folha e novamente chama a mesma função, agora com n=2.
A partir de n=2, a função planta passa a desenhar as inflorescências alternadamente entre esquerda e direita, até que em n=6 é desenhado o topo da planta.

Abaixo segue o comando para execução das funções:

if __name__ == '__main__':
    begin_fill() 
    screensize(200,1000)
    up()    
    setpos(0,0)  
    down()  
    lt(90)
    planta(0, 50, 30, 80, 5)
    up()
    setpos(0,0)
    end_fill()

E abaixo o resultado ao executar o comando acima:

A imagem será apresentada aqui.

...