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

Como desenhar o fractal "Gosper Hexagonal Curve" com recursão usando o Python?

+1 voto
205 visitas
perguntada Abr 21, 2017 em Ciência da Computação por Carlos Eduardo Véras (11 pontos)  
editado Abr 24, 2017 por Carlos Eduardo Véras

Em seu livro "The Algorithmic Beauty of Plants ", Przemyslaw Prusinkiewicz e Aristid Lindenmayer exploram as questões matemáticas e algorítmicas que explicam a beleza e a elegância da estrutura das plantas. São explorados os algorítimos de desenvolvimento e a característica denominada auto-similaridade (cada parte da geometria do objeto é similar ao todo).

Entre as questões abordadas pelos autores, está a modelagem gráfica de árvores utilizando os chamados L-Systems (Lindenmayer systems). Os L-Systems foram concebidos como uma teoria matemática para explicar o desenvolvimento das plantas. Posteriormente, diversas interpretações geométricas para os L-Systems possibilitaram a sua aplicação como ferramenta versátil para a modelagem de plantas.

O conceito central nos L-Systems é a reescrita. A reescrita é uma técnica de definição de objetos complexos por meio da substituição das partes de um objeto inicial simples utilizando uma série de regras de reescrita ou produção. Os L-Systems são baseados na reescrita de "strings" ("strings rewriting").

Para a interpretação dos L-Systems é possível aplicar um objeto denominado "turtle". O "turtle" é uma tríade do tipo (x, y, α) , onde as coordenadas cartesianas (x,y) representam a posição do "turtle" no espaço, enquanto α é um ângulo que define a direção para a qual o "turtle"está apontando. Dados os parâmetros "d" (comprimento do passo) e δ (incremento angular), o "turtle"pode responder aos comandos representados pelos seguintes símbolos:

  • F : mova para frente um passo com o comprimento "d" . O estado do "turtle"irá ser alterado para (x', y', α), onde x' = x + d cos α e y' = y + d sen α. Um segmento de reta entre os pontos (x, y) e (x', y') é então desenhado;

  • f: mova um passo adiante com o comprimento d sem desenhar uma linha;

  • (+) : Vire à esquerda por um ângulo δ. O próximo estado do "turtle" será (x, y, α+δ). A orientação positiva de ângulos é anti-horária;

    − (-): Vire à direita por um ângulo δ. O próximo estado do "turtle" será (x, y, α − δ).


Após esta breve explicação, fica mais fácil responder a pergunta "Como reproduzir a figura 1.11(a) do livro The Algorithmic Beauty of Plants (Przemyslaw Prusinkiewicz e Aristid Lindenmayer)?"

A figura mencionada é a Curva de Gosper hexagonal (abaixo).

A imagem será apresentada aqui.

Compartilhe
comentou Abr 24, 2017 por danielcajueiro (5,376 pontos)  
Carlos, vc colocou sua pergunta e resposta na pergunta. Vc pode separar editando a pergunta, recortando a parte da resposta e colando na resposta!
comentou Abr 24, 2017 por Carlos Eduardo Véras (11 pontos)  
Professor, por favor, verifique se agora melhorou. Eu, de fato, havia esquecido de dividir pergunta e reposta.

1 Resposta

0 votos
respondida Abr 24, 2017 por Carlos Eduardo Véras (11 pontos)  

Para facilitar o desenho de figuras geométricas usando os L-Systems, o Python possui um módulo denominado "turtle graphics for TK", o qual já está presente na instalação padrão de distribuições como a Anaconda 3.

O módulo "turtle graphics for TK" possui os métodos necessários para o desenho por meio da interpretação "turtle".

Portanto, para reproduzir a Curva de Gosper hexagonal, pode-se implementar o seguinte código:

"""
    Faz um desenho da Gosper Hexagonal Curve por meio do turtle t de ordem - 'order' -  e tamanho - 'size'.
    O Código para o desenho da Gosper Hexagonal Curve é o seguinte:

    n=4, δ=60◦
    Fr
    Fr→ -Fl+FrFr++Fr+Fl--Fl-Fr
    Fl→  Fl+Fr++Fr-Fl--FlFl-Fr+


"""
import turtle

def rgosper(t, order, size):
    """
    Fr→ -Fl+FrFr++Fr+Fl--Fl-Fr

    right Gosper

    """


    if order == 0:   # ordem 0      

        t.right(60)
        t.forward(size)
        t.left(60)
        t.forward(size)
        t.forward(size)
        t.left(60)
        t.left(60)
        t.forward(size)
        t.left(60)
        t.forward(size)
        t.right(60)
        t.right(60)
        t.forward(size)
        t.right(60)
        t.forward(size)


    else: # ordem k - 1

        t.right(60)
        lgosper(t, order-1, size)
        t.left(60)
        rgosper(t, order-1, size)
        rgosper(t, order-1, size)
        t.left(60)
        t.left(60)
        rgosper(t, order-1, size)
        t.left(60)
        lgosper(t, order-1, size)
        t.right(60)
        t.right(60)
        lgosper(t, order-1, size)
        t.right(60)
        rgosper(t, order-1, size)


def lgosper(t, order, size):

    """
    Fl→  Fl+Fr++Fr-Fl--FlFl-Fr+

    left Gosper


    """

    if order == 0:  # ordem 0      

        t.forward(size)
        t.left(60)
        t.forward(size)
        t.left(60)
        t.left(60)
        t.forward(size)
        t.right(60)
        t.forward(size)
        t.right(60)
        t.right(60)
        t.forward(size)
        t.forward(size)
        t.right(60)
        t.forward(size)
        t.left(60)

    else: # ordem k-1 

        lgosper(t, order-1, size)
        t.left(60)
        rgosper(t, order-1, size)
        t.left(60)
        t.left(60)
        rgosper(t, order-1, size)
        t.right(60)
        lgosper(t, order-1, size)
        t.right(60)
        t.right(60)
        lgosper(t, order-1, size)
        lgosper(t, order-1, size)
        t.right(60)
        rgosper(t, order-1, size)
        t.left(60)


if __name__ == "__main__":

    t = turtle.Turtle() # objeto turtle

    turtle.tracer(100)
    turtle.hideturtle()
    t.penup()
    t.setx(-250)
    t.sety(-250)
    t.pendown()
    rgosper(t, 4, 5) # n = 4; size = 5

    turtle.update()
    turtle.done()
    turtle.Screen().exitonclick()

Com o código acima o resultado obtido é:

\[1\]: http://prorum.com/?qa=blob&qa_blobid=6365339289663311454

comentou Jul 7, 2017 por Pedro Antero (26 pontos)  
Excelente explicação! O código está funcionando perfeitamente!
Apenas como curiosidade, creio que para obter exatamente a figura do livro, o critério de "saída" da recursão deve ser "if order == 1". Esse deve ter sido o critério estabelecido pelo autor quando definiu a ordem=4 para a figura que está no livro. O que acha?
...