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

Como gerar imagens de árvores utilisando sistemas de Lindenmayer estocásticos?

+1 voto
47 visitas

1 Resposta

+1 voto
respondida Jun 24 por Jonas Santana (11 pontos)  

O problema consiste em gerar imagens da forma

Figura 1
A imagem será apresentada aqui.

As quais obedecem à função de geração:

Figura2
A imagem será apresentada aqui.

A resposta desse problema se baseou fortemente na resolução de http://prorum.com/?qa=3112/como-desenhar-arvores-usando-pilhas-e-recursoes

Iniciaremos importando a biblioteca "turtle", utilizada para plotar nossa árvore bidimensionalmente, e a biblioteca random, utilizada para gerar números aleatórios.

from turtle import *
import random

Em seguida, definiremos duas funções, a primeira retorna o posicionamento do ponteiro responsável pelo desenho e a segunda define o novo posicionamento desse (ângulo e ponto no plano). Também definiremos uma classe, responsável por comandar a ordem das ações a serem executadas.

def get_turtle_state(t_obj):
    return t_obj.heading(), t_obj.position()

def set_turtle_state(t_obj, state):
    t_obj.setheading(state[0])
    t_obj.setposition(state[1][0], state[1][3])

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)

Então, criamos a função recursiva de geração dos galhos para cada um dos níveis "n". Entretanto, agora inserimos o aspecto aleatório do programa descrito na Figura 2.

def build_branch_level_f(n):
    n = n - 1
    if n >= 0:
        opt = random.choice([1,2,3])
        build_branch_level_f(n)
        if opt == 1:
            build_branch_level_f(n)
            t_s.push(get_turtle_state(turtle))
            turtle.left(delta)
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()
            build_branch_level_f(n)
            t_s.push(get_turtle_state(turtle))
            turtle.right(delta)
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()
            t_s.push(get_turtle_state(turtle))
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()

        if opt == 2:
            build_branch_level_f(n)
            t_s.push(get_turtle_state(turtle))
            turtle.left(delta)
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()
            t_s.push(get_turtle_state(turtle))
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()

        if opt == 3:
            build_branch_level_f(n)
            t_s.push(get_turtle_state(turtle))
            turtle.right(delta)
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()
            t_s.push(get_turtle_state(turtle))
            build_branch_level_f(n)
            turtle.penup()
            set_turtle_state(turtle, t_s.pop())
            turtle.pendown()

    else:
        turtle.forward(8)

Por conseguinte, definimos o número "n" de níveis e a angulação "delta":

turtle = Turtle()
t_s = Stack()

turtle.pensize(2)
level = 4
delta = 20

turtle.penup()
turtle.right(90)
turtle.forward(450)
turtle.left(180)
turtle.pendown()
build_branch_level_f(level)

Obtemos árvores que aparentam pertencer à mesma espécie das presentes na Figura 1:

Figura 3
A imagem será apresentada aqui.

Figura 4
A imagem será apresentada aqui.

Figura 5
A imagem será apresentada aqui.

comentou Jun 28 por vanderson Delapedra (21 pontos)  
Olá Jonas, primeiramente, parabéns, a questão está muito bem explicada. Se eu fosse fazer algumas pequenas sugestões , talvez fosse interessante explicar que o código também pode inserir opções de cores. Ah, o link indicado deve ter alguma problema, eu acesse sua referência pelo nome no campo de busca, pois o link leva a uma página de erro. Grande abraço.
comentou Jul 6 por Edmar Rocha Pereira (21 pontos)  
Oi Jonas! só agora que vi que tinha feito a mesma questão que você! Fica como complemento da sua!

Abraços, Edmar
...