Fractais Geométricos





Introdução

Alguns fractais, como os exemplos deste programa, possuem auto-semelhança exacta, isto é, têm sempre o mesmo aspecto visual independentemente da escala a que os observamos, porque o todo é exactamente igual à ampliação de uma das partes. Esta propriedade resulta do facto de serem construídos pela iteração 'ad infinitum' da mesma regra de construção.

Muitas formas na natureza são aproximadas por esta geometria. No entanto, os fractais apresentados neste programa não foram inventados para simular as propriedades de padrões naturais, mas sim para mostrar que a matemática continha mais objectos para além das curvas e superfícies regulares da geometria tradicional.

Considere o exemplo da famosa curva de Koch, criado em 1904 pelo matemático sueco Helge von Koch. Começa-se com um segmento de recta. Ao objecto inicial da construção chama-se "iniciador". De seguida divide-se o segmento inicial em três segmentos iguais. Depois disto substitui-se o terço do meio por um triângulo equilátero tirando-lhe a sua base. Neste momento completou-se a construção da unidade fundamental, o "gerador". A iteração deste processo consiste em aplicar a mesma regra a cada um dos segmentos de recta que resultam da iterada anterior, como se ilustra na figura. A curva de Koch é o objecto que se obtem no limite em que o número de iterações tende para infinito.

A auto-semelhança é um ingredientes do processo de construção. Cada segmento de recta contido na iterada k está reduzido por um factor de 3 em relação aos segmentos de recta que compõem a iterada anterior, e cada um dos quatro troços que compõem a iterada k é uma cópia, reduzida por um factor 3, de toda a estrutura da iterada imediatamente anterior.

Por isso, o objecto que resulta da passagem ao limite deste processo recursivo é exactamente auto-semelhante, é igual a uma cópia ampliada dos elementos que o constituem. Este objecto exótico tem o nome de curva, mas é uma curva que não contem nenhum segmento de recta e não pode ser diferenciada em nenhum dos seus pontos (é uma curva em que todos os pontos são "bicos").

Início

Utilização

O programa permite seleccionar a construção de diferentes fractais geométricos. Por exemplo, para gerar a Árvore de Sierpinski, começa-se por escolher um ponto no plano e desenha-se três segmentos de recta desde esse ponto até aos vértices de um triângulo equilátero centrado no ponto inicial.

A segunda iteração do processo obtem-se aplicando a mesma operação sobre os vértices do triângulo considerados como novos pontos iniciais, e tomando segmentos de recta de comprimento metade dos da iteração anterior. A Árvore de Sierpinski é o fractal que resulta de iterar indefinidamente esta regra de construção.

Pode ver este procedimento posto em prática seleccionando a Árvore de Sierpinski e pressionando vezes sucessivas o botão "Desenhar uma iteracao". Pressionando este botão executa-se uma só vez a regra usada para a construção do fractal seleccionado. O botão "Desenhar" ("forever button") executa exactamente o mesmo procedimento que "Desenhar uma iteracao", mas executa-o até o utilizador voltar a pressioná-lo.

O botão quadrado de Sierpinski utiliza uma regra similar a esta com outra simetria. Premindo o botão Quadrado de Sierpinski 2 segue-se um esquema de desenho do fractal ligeiramente diferente do anterior. A ideia é dividir o quadrado inicial em nove quadrados iguais, retirar o do meio e aplicar indefinidamente este procedimentos ao quadrados restantes ao fim de cada iteração. Este é também um dos métodos de obtenção do Triângulo de Sierpinski. Finalmente, o programa permite ainda gerar a ilha de Koch, uma variante da curva de Koch.

O utilizador pode modificar o aspecto visual do seu fractal escolhendo a cor da primeira turtle criada ("cor-inic"). As turtles das gerações seguintes terão uma cor que corresponde à cor da sua "progenitora" incrementada de "cor-incremento" (ver representação numérica das cores no manual do utilizador).

Desta maneira, o código de cores permite visualizar o resultado das sucessivas iterações da regra de construção.

A interface apresenta ainda o botão "Exportar Mundo", que serve para armazenar num ficheiro o padrão gerado na janela. Utilizaremos esta funcionalidade para importar as imagens dos fractais geométricos para o programa de cálculo da dimensão de contagem de caixas.

Início

Questões

1) Para se criar o Quadrado de Sierpinski o método utilizado foi o mesmo que para a Árvore, só que a regra mudou. Qual será a regra usada?

2) Qual é o limite a partir do qual a figura não se altera com sucessivas iterações da regra? Faça uma estimativa do número de iterações correspondente.

3) Note a auto-semelhança dos objectos a cada iteração. Iterando um número finito de vezes, notar-se-ía alguma diferença entre uma ampliação de uma parte da figura e toda a figura?

4) Quais são as diferenças entre o Triângulo e a Árvore de Sierpinski e entre o Quadrado de Sierpinski 2 e o Quadrado de Sierpinski ?

5) Note que o número de turtles em cada iteração vai sempre aumentando de um factor constante. Determine esse factor e preveja o o número de turtles numa iterada qualquer n. Relacione este cálculo com a taxa de aumento do aumento exponencial do tempo de desenho com n.


Início

Breve Análise do Código

Conceito Geral

Neste modelo começamos por definir para cada tipo de fractal uma função de preparação e outra de iteração para cada um dos tipos de fractal: ArvoreSierpinski, koch ou QuadradoSierpinski.

A primeira função limpa e inicializa as variáveis de acordo com o fractal pretendido, e de seguida cria uma turtle.

A segunda função itera o fractal de acordo com as regras correspondentes ao tipo de fractal escolhido.

Em cada iteração cria-se na posição das últimas tartarugas N novas tartarugas e de seguida, rodando-as e movendo-as de acordo com as regras do fractal traçam N novas linhas desde a posição das tartarugas da iteração anterior até às posições correspondentes à nova iteração.

De forma a poder criar novas turtles apenas nas posições das turtles da última iteração, definiu-se uma propriedade nova das turtles (nova?) que quando se encontra verdadeira (true) corresponde às turtles da iteração anterior. De cada vez que se itera o fractal, as turtles com a propriedade nova? = true passam a false e criam-se N turtles novas com a propriedade nova? = true.

Variáveis globais
turtles,nova?serve para manter um registo da últimas turtles criadas.
Qsierpinski?,Qsierpinski2?,Asierpinski,koch?servem para escolher o tipo de fractal que se pretende gerar
compdefine o comprimento da linha que cada tartaruga irá traçar numa dada iteração e é actualizada de iteração em iteração
primeira-passagem?utilizada para indicar caso se esteja a efectuar a primeira iteração.
Nutilizada na geração do Quadrado de Sierpinski para manter a comprimento do lado do quadrado.
cormantem a cor da última iteração
Funções principais
desenharchama a função iterativa correspondente ao fractal escolhido
Funções auxiliares
tpara todas as turtles antigas cria uma nova turtle
dir rotroda todas as tartarugas antigas rot graus para a direita
esq rotroda todas as tartarugas antigas rot graus para a esquerda
frente pmove as turtles antigas para a frente p passos traçando uma linha com a cor da turtle ao longo da trajectoria
salta pmove as turtles antigas para a frente p passos mas sem traçar linha
mmata todas as turtles antigas
muda_corchamada de iteração em iteração para incrementar a cor das turtles
exportarmundoexporta a imagem do fractal para um ficheiro que depois será utilizado no programa de cálculo da dimensão

Código

Variáveis Globais

Começamos por definir uma propriedade adicional das turtles "nova?" e declarar as variáveis globais utilizadas neste programa.

turtles-own  ;variável das turtles que indica se cada uma foi ou não criada na iteração corrente
[ nova? ]

globals
[
  comp                 ;comprimento
  Qsierpinski?         ;
  Qsierpinski2?        ; 
  Asierpinski?         ;
  koch?                ;;indicam a opção do utilizador quanto ao fractal a desenhar
  primeira-passagem?
  N                    ; variável auxiliar (indica o número de patches de um lado do quadrado) 
  cor                  ; mantem a cor da última iteração
]
Funções principais
desenhar

A função desenhar exposta a seguir, apenas chama a função iterativa correspondente ao fractal escolhido. Avisando o utilizador caso não tenha sido selecionado nenhum tipo de fractal. Avisando tambem caso a resolução máxima tenha sido atingida para o fractal do quarado de Sierpinski.

  ;procedimento que é executado sempre que se pressiona Desenhar uma iteração ou Desenhar
to desenhar
  if Asierpinski? = 0 and koch? = 0 and Qsierpinski? = 0 and Qsierpinski2? = 0
    [ user-message "Escolha um fractal!" stop ]
  ifelse (Asierpinski?)
    [ ArvoreSierpinski ]
    [
     ifelse (koch?)
       [ IlhaKoch ]
       [
        ifelse (Qsierpinski?) 
          [ QuadradoSierpinski ]
          [ 
             ;Se N for menor que 1 atingiu-se a resolução máxima deste programa 
           if 1 > N [ user-message "Atingiu a resolução máxima" stop ]
           QuadradoSierpinski2
          ] 
       ]
    ]
end
Funções auxiliares
t
;para cada turtle antiga, na iteração corrente, cria uma turtle nova e
;inicializa a sua variável nova? com o valor lógico verdadeiro
to t
  ask turtles with [ not nova? ]
    [
      set color cor
      hatch 1 [ set nova? true ]
    ]
end
muda_cor
;muda a cor das tartarugas de iteração em iteração, de acordo
;com o incremento
to muda_cor
  set cor cor + cor-incremento
  if cor = black
    [ set cor cor + cor-incremento ]
  ask turtles with [ nova? ]
    [ set color cor ]
end
dir
;roda cada turtle com nova? = falso (isto é que não foi criada durante a presente iteração) 
;gr graus à direita
to dir [ gr ]
  ask turtles with [ not nova? ] [ rt gr ]
end
esq
;cada turtle com nova? = falso vira gr graus à esquerda
to esq [ graus ]
  ask turtles with [ not nova? ] [ lt gr ]
end
frente
;move todas as turtles com nova? = falso em frente o numero de passos
;dado no argumento
to frente [ passos ]
  ask turtles with [ not nova? ] [ fd passos ]
end
salta
;move todas as turtles com nova? = falso em frente o numero de passos
;dado no argumento mas sem pintar os patches por debaixo
to salta [ passos ]
  ask turtles with [ not nova? ] [ pu fd passos pd ]
end
m
;mata todas as turtles não novas (i.e. com a variável nova? igual a falso)
to m
  ask turtles with [ not nova? ] [ die ]
end
exportarmundo

Por fim temos uma função que exporta a imagem do fractal para um ficheiro que depois será utilizado no programa de cálculo da dimensão.

;exporta o mundo (escreve o valor de todas as variáveis)
;para um ficheiro de nome nomeficheiro 

to exportarmundo        
 locals [nomeficheiro]
 set nomeficheiro user-input "Nome do ficheiro da saída:"
 export-world nomeficheiro
end
Funções da Árvore de Sierpinski

Para cada tipo de fractal definimos adiante uma função "setup" e uma função de iteração (cujo nome é o do fractal)

  ;inicializa as variáveis necessárias para seguidamente se efectuar o desenho da Árvore de Sierpinski 
to AsierpinskiSetup
  ca
  crt 1
  set cor cor-inic
  ask turtles
  [
    set shape "line"
    set color cor-inic
    setxy 0 -70
    set heading 0
    pd
  ]
  set comp 140
  set Asierpinski? true   ;indica a opção do utilizador quanto ao objecto a desenhar
  set koch? false
  set Qsierpinski? false
  set Qsierpinski2? false
end

Na função setup da arvore de sierpinski, é criada uma tartaruga inicializando-se a sua cor. E por fim inicializa-se tambem a variavel comprimento e acertam-se as variáveis que escolhem o tipo de gráfico a desenhar.

to ArvoreSierpinski
  ;a cada nova iteração, as turtles existentes passam a antigas para essa iteração 
  ask turtles [ set nova? false pd ]
  repeat 3     ;regra de construção
    [
      frente comp
      t
      dir 180
      salta comp
      dir 180
      dir 120
    ]
  muda_cor
  set comp (comp / 2)
  m
end

Na função de iteração da árvore de sierpinski, em cada iteração alteramos a propriedade nova? das turtles igualando-a false. De seguida movemos as tartarugas antigas em frente traçando uma linha de comp passos, chamando a função t criam-se N novas turtles, rodamo-la para a direita 180°, com o comando salta deslocamos as turtles antigas (sem traçar qualquer linha) em frente comp passos. E de seguida rodam-se as turtles de novo por 300° para a direita.

Funções da Ilha de Koch

Repete-se 3 vezes as instruções anteriores, actualiza-se o comprimento dos passos a dar pelas turtles. E por fim eliminam-se todas as tartarugas não criadas nessa iteração com o comando m.

  ;inicializa as variáveis necessárias para seguidamente se efectuar o desenho da Ilha de Koch 
to kochSetup
  ca
  crt 1
  set cor cor-inic
  ask turtles
    [
      set shape "line"
      set color cor-inic
      setxy -121 -210
      set heading 0
      pd
    ]
  set comp 140
  set Asierpinski? false
  set koch? true
  set Qsierpinski? false
  set Qsierpinski2? false
  set primeira-passagem? true
end

Prepara-se da mesma forma o fractal de koch, embora para posições iniciais diferentes da turtle

to IlhaKoch
  ;a cada nova iteração, as turtles existentes passam a antigas para essa iteração
  ask turtles [ set nova? false pd ]
  ifelse (primeira-passagem?)
    [
      set primeira-passagem? false

        ;na primeira passagem por este procedimento estas regras são executadas 3 vezes
	;para que se obtenha a forma de ilha
      repeat 3
        [
          t frente comp esq 60 t frente comp dir 120 t frente comp esq 60 t frente comp dir 120
        ]
    ]
    [  ;note que estas regras são as mesmas que as anteriores, só que agora só são executadas uma vez
      t frente comp esq 60 t frente comp dir 120 t frente comp esq 60 t frente comp dir 120
    ]
  muda_cor
  set comp (comp / 3)
  m
end

Neste caso faz-se uso da variável global primeira-passagem? para na primeira passagem se repetirem 3 vezes as regras de actualização

Em cada actualização cria-se na posição das turtles antigas uma turtle nova e traçando a linha de koch, criam-se mais 2 tartarugas em cada vértice, obtendo-se assim passo a passo o fractal de koch

Funções do Quadrado de Sierpinski

Como nos outros fractais, este tambem tem as funções de preparação e de iteração.

  ;inicializa as variáveis necessárias para seguidamente se efectuar o desenho do quadrado de Sierpinski
to QsierpinskiSetup
  ca
  crt 1
  set cor cor-inic
  ask turtles
    [
      set shape "line"
      set color cor-inic
      setxy 0 0
      set heading 0
      pd
    ]
  set comp 128
  set Asierpinski? false  ;indica a opção do utilizador quanto ao objecto a desenhar
  set koch? false
  set Qsierpinski? true
  set Qsierpinski2? false
end

to QuadradoSierpinski
  ask turtles
    [ set nova? false pd ]
  ask turtles[ set heading 0 ]     
  repeat 4   ;regra de construção. Para se perceber como a regra foi refinada apresenta-se 
    [        ;a versão antiga, está comentada e apresenta-se a versão actual.
	     ;Experimente a descomentar essas duas linhas e 
	     ;comentar as seguintes indicadas por ; à direita 
      ;frente comp        
      salta comp / 2   ; 
      frente comp / 27 ; 
      salta comp / 27  ;
      frente comp / 27 ; 
      salta comp / 9   ;
      frente comp / 27 ;
      salta comp / 27  ; 
      frente comp / 27 ;
      salta comp / 6   ;
      t
      dir 180
      salta comp
      esq 135
      ;frente (comp * sqrt 2) 
      salta (comp * sqrt 2) / 2   ;
      frente (comp * sqrt 2) / 27 ;
      salta (comp * sqrt 2) / 27  ;
      frente (comp * sqrt 2) / 27 ;
      salta (comp * sqrt 2) / 9   ;
      frente (comp * sqrt 2) / 27 ;
      salta (comp * sqrt 2) / 27  ;
      frente (comp * sqrt 2) / 27 ;
      salta (comp * sqrt 2) / 6   ;
      t
      dir 180
      salta (comp * sqrt 2)
      esq 135
    ]
  muda_cor
  m
  set comp comp / 3         
end

Neste caso as turtles desenham os quadrados mais pequenos deslocando-se dos vértices do quadrado exterior para os quadrados mais pequenos e de seguida, percorrendo o lado dos quadrados correspondente a essa iteração. A variável comp é neste caso utilizada para o lado do quadrado e é reduziada para um terço de iteração em iteração.

Funções do Quadrado de Sierpinski 2

Para esta versão do quadrado de Sierpinski, em vez de se implementar usando turtles, utilizou-se as patches para obter uma variação.

Assim, o modelo começa por pintar um quadrado maior e ir sucessivamente retirando (pintando da cor preta) quadrados mais pequenos de acordo com as regras de iteração.

;Para o desenho do Quadrado de Sierpinski 2 o procedimento usado
;é diferente do procedimento usado anteriormente
;aqui não se faz uso do agente turtles

 ;inicializa as variáveis necessárias para seguidamente
 ;se efectuar o desenho do quadrado de Sierpinski 
to QsierpinskiSetup2
  ca
  ask patches with[ 121 >  pxcor and 121 > pycor and pxcor > -121 and pycor > -121 ]
    [ 
       ;pinta o quadrado inicial, tem um lado de 243=3^5 para
       ;que se possa chegar à resolução do patch (=pixel)            
      set pcolor cor-inic
    ]
  set comp 81 ;lado de cada quadrado em que se dividiu o quadrado maior  
  set N 81    ;indica o número de patches do lado do quadrado da maior divisão pretendida
              ;no início é 81 pois não se quer fazer divisão nenhuma 
  set Asierpinski? false
  set koch? false
  set Qsierpinski? false
  set Qsierpinski2? true
end

to QuadradoSierpinski2   
    ;Função recursiva que dado a posição do quadrado e lado, desenha todos os outros quadrados
  DesenhaNivelN (- 121) (- 121) comp
    ;passa-se para uma divisão maior, ou seja, um lado do quadrado menor 
  set N N / 3
end

  ;função recursiva que se chama a ela própria até "comprini" (comprimento inicial) ser igual a N
to DesenhaNivelN [ pxcorini pycorini compini ]
  ifelse N = compini
    [
        ;se os dois comprimentos forem iguais então a partição pretendida
	;foi atingida e pinta o quadrado central 
      qDesenha pxcorini pycorini compini
    ]
    [             
        ;se o comprimento não foi atingido chama-se novamente
	;nos quadrados mais pequenos (excepto no central)
      DesenhaNivelN pxcorini pycorini (compini / 3)  
      DesenhaNivelN (pxcorini + compini) pycorini (compini / 3)  
      DesenhaNivelN (pxcorini + 2 * compini) pycorini (compini / 3)  
      DesenhaNivelN pxcorini (pycorini + compini) (compini / 3) 
      DesenhaNivelN (pxcorini + 2 * compini) (pycorini + compini) (compini / 3)  
      DesenhaNivelN pxcorini (pycorini + 2 * compini) (compini / 3) 
      DesenhaNivelN (pxcorini + compini) (pycorini + 2 * compini) (compini / 3)  
      DesenhaNivelN (pxcorini + 2 * compini) (pycorini + 2 * compini) (compini / 3)  
    ]
end

;dado um quadrado cujas coordenadas do canto inf. esq. são (qpxcor,qpycor) e
;o cujo lado é qcomp, esta função divide-o 
;em nove quadrados iguais e pinta de negro o quadrado do meio
to qDesenha [ qpxcor qpycor qcomp ]
  ask patches with [ pxcor >= (qpxcor + qcomp) and 
                     (2 * qcomp + qpxcor) > pxcor and 
		     pycor >= (qpycor + qcomp) and 
		     (2 * qcomp + qpycor) > pycor ]
    [ set pcolor black ]
end

Início

Variantes e Extensões

Experimente fazer os seus próprios fractais! Para isso crie um botão (análogo aos existentes) que inicializa as variáveis necessárias para desenhar o seu fractal. De seguinda escreva uma função onde estarão as regras para a construção do seu fractal e coloque-a no procedimento Desenhar.
Construa as suas regras com as funções já criadas ou com outras que crie (p.e. frente 5 dir 90 salta 3 m). Basta seguir o exemplo dado pelo próprio programa.

Em baixo está a regra que cria o fractal Recobrimento Universal da Figura Oito. Experimente esta!

 

                   .               Passo 0                  

    
                                                            
                   |                                        
                   |                                        
                   |                                        
            ______________         Passo 1                  
                   |                                        
                   |                                        
                   |                                        

                            
 
                   |                                        
                 __|__                                      
                   |                                        
                   |                                        
           __|___________|__       Passo 2                  
             |     |     |                                  
                   |                                        
                 __|__                                      
                   |                                        

Procure outros fractais e tente representá-los usando as regras deste programa ou outras.


Início