Cálculo da Dimensão Fractal



Introdução

Nem comprimento nem área servem para medir o tamanho dos objectos fractais. Por exemplo, todos os fractais geométricos que construímos com o primeiro programa deste módulo têm comprimento infinito e área zero. São "mais" do que linhas, e "menos" do que superfícies. O conceito de dimensão fractal dá uma resposta ao problema de medir o tamanho destes objectos.

Para os objectos geométricos ‘clássicos’ existe uma relação simples entre a dimensão, o número de blocos necessário para os recobrir, e o tamanho dos blocos. No caso de segmentos de recta, quadrados, ou cubos, conforme estejamos em dimensão um, dois ou três, essa relação é Nn = (1/ Ln)^d, onde Nn é o número de quadrados de lado Ln do recobrimento e d a dimensão. È fácil comprovar este resultado. Por exemplo, um quadrado de lado 1 é recoberto por 4 quadrados de lado 1/2, 16 quadrados de lado 1/4, ...

A equação anterior pode ser rescrita na forma d = log Nn /log (1/Ln) que põe em evidência a simplicidade desta lei. É uma lei de potência, portanto a dependência do logaritmo do número de blocos no logaritmo do inverso do tamanho destes é linear. Num gráfico log-log, esta relação traduz-se por uma recta, e o declive dessa recta é a dimensão, d.

Para objectos de formas mais complicadas, a equação anterior pode não se verificar. No entanto, a relação de proporcionalidade d ~ log Nn /log (1/Ln) (1) é recuperada assimptoticamente à medida que o recobrimento se toma mais fino.

Isto motiva tomar a relação (1), no limite Ln->0, como uma definição alternativa de dimensão, chamada dimensão de contagem de blocos, por razões óbvias. A dimensão definida desta maneira coincidirá com a dimensão habitual para os objectos da geometria tradicional, e é em geral não inteira para os objectos fractais. É uma das definições posíveis de dimensão fractal, e é nela que se baseia o cálculo que este programa executa.

O cálculo da dimensão de contagem de blocos para a ilha de Koch dá d = log 4/ log 3 ~ 1.26 . A curva de Koch tem dimensão fractal não inteira, maior que a de uma linha, e menor que a de uma superfície. O mesmo cálculo para a árvore de Sierpinski dá d = log 3/ log 2 ~ 1.58, e para o quadrado de Sierpinsky d = log 8/ log 3 ~ 1.89. Não é difícil verificar que, em geral, para fractais construídos recursivamente como nestes exemplos a partir de c cópias de si próprios rescaladas por um factor 1/f, se terá d = log c/ log f.

Note que a dimensão de contagem de blocos é um limite, e que um fractal 'autêntico' tem estrutura não trivial em todas as escalas, enquanto que nos objectos com que trabalhamos aqui o detalhe está limitado pela resolução da figura. Pela mesma razão, não faz sentido construir recobrimentos mais finos do que o tamanho de um pixel.



Início

Utilização

Este programa usa o algoritmo da dimensão de contagem de blocos para obter valores aproximados para a dimensão fractal das figuras representadas na janela gráfica. Essas figuras podem ser desenhadas 'à mão' neste programa, premindo o botão "DESENHAR" e 'clickando' ou arrastando o rato na janela gráfica para aí criar uma imagem. Também podem ser importadas de outros programas, premindo o botão "IMPORTAR MUNDO" para carregar na janela gráfica ficheiros previamente criados.

Como viu, a ideia para o cálculo da dimensão de contagem de blocos de uma imagem é muito simples. Basta dividir a janela gráfica em quadrados cada vez mais pequenos e ir contando quantos desses quadrados possuem pelo menos um patch que faça parte da imagem. O programa executa essa operação com o botão "CALCULA DIMENSÃO", e vai representando num gráfico log Nn em função de log (1/Ln). À medida que a partição se torna mais fina, esses pontos aproximam-se de uma recta cujo declive é um valor aproximado da dimensão fractal. Esse valor é apresentado na janela de comandos no fim do cálculo.

A opção "VER-PARTIÇÃO" permite ao utilizador ver como é que a imagem está a ser coberta pelos quadrados da partição. Os quadrados que ficam a verde fazem parte da aproximação ao objecto, os outros quadrados da partição ficam azuis. O monitor "Células Ocupadas" dá a indicação do número de quadrados verdes em cada partição.


Início

Questões

1. Use o botão "DESENHAR" para criar imagens na janela gráfica e calcule a dimensão de contagem de blocos destas imagens. Procure desenhar áreas e linhas regulares, e conjuntos de pontos, e analise os resultados. Em particular, procure explicar o comportamento dos pontos que se obtêm à medida que a partição se torna mais fina.

2. Calcule a dimensão de contagem de blocos dos fractais gerados pelo programa Fractais Geométricos, e compare com os valores exactos.

3. Calcule a dimensão de alguns dos fractais gerados pelo programa Atractores Estranhos, incluindo o atractor de Hénon (d ~ 1.26).

4. Calcule a dimensão da fronteira da região percorrida por uma tartaruga no programa Marcha Aleatória (d ~ 4/3).

5. Repare que em todos os cálculos que efectuou, o programa ajusta a recta aos penúltimo e antepenúltimo pontos, em vez de aos dois últimos. Esta escolha altera de maneira sistemática a estimativa da dimensão ? Parece-lhe razoável desprezar o ponto que corresponde à partição mais fina ?

6. No módulo 1, no programa Infiltração de Óleos em Solos Porosos, para a porosidade correspondente à transição de percolação o solo contaminado forma um agregado fractal. Calcule a sua dimensão fractal (não se esqueça de alterar as cores convenientemente, assim como o tamanho e propriedades da janela gráfica, e use as funções "export world" e "import world" que o programa disponibiliza em 'file' ).


Início

Breve Análise do Código

Conceito Geral

O principal conceito deste programa prende-se com a contagem de quadrados de vários tamanhos que incluem ou não uma célula pintada no seu interior. Traçando o gráfico deste número dividido pelo número total de quadrados existentes na caixa de visualização em função do lado dos quadrados escolhidos, pode-se obter a dimensão da figura achando o declive da recta emergente.

Desta forma a ideia adoptada para verificar quais os quadrados que possuiem células pintadas foi a seguinte. Definindo um lado l para o quadrado, todas as células dentro de um determinado quadrado são representadas por uma só célula (do canto inferior esquerdo (0,0) desse quadrado). Assim, faz-se um ask a todas as células que caso estejam pintadas calculem o seu representante e incrementem a sua propriedade pintado. No final apenas é preciso contar o número de representantes cuja propriedade pintado é não nula

Variáveis globais
tempomantem o tempo de cálculo
portaavisa quando o utilizador pretende interromper o cálculo
NP(Número Pintado), número de quadrados pintados
verde, azulcores definidas para a visualização
patches: pintadopropriedade das patches onde é guardada a informação dos representantes
Funções principais
calculadimensaofunção executada quando premido o botão "calcular dimensão"
Funções auxiliares
inicializagraficolimpa e inicializa o gráfico traçando as rectas correspondentes á dimensão 1 e 2
representanteschamada pelas patches para incrementar a propriedade pintado do seu representante
desenhapontomarca um ponto no gráfico
tangentetraça no gráfico a recta tangente aos pontos calculados
apagarlimpa e inicializa as variáveis do programa
desenharexecutada quando o utilizador prime o botão "desenhar", permite o utilizador acrescentar pontos no gráfico
pararavisa a função calculadimensao que o utilizador pretende parar o cálculo
importarmundoexecutada quando o utilizador prime o botão com o mesmo nome, mostra uma janela onde o utilizador escolhe um ficheiro gerado anteriormente por outro modelo de fractais.

Código

Variáveis globais
globals [        ;Declaração das variáveis globais.
         tempo   ;Permite saber o tempo de cálculo.
	 porta   ;O valor lógico desta variável 
	         ;determina se o programa é ou não abortado.
		 
         NP      ;Número de células pintadas para cada partição.   
            
	 azul    ;Nomear duas cores que tal como o "black" não podem
	 verde   ;fazer parte dos objectos a calcular a dimensão.
                 
		 ;O verde será a cor dos diversos quadrados que aproximam o objecto.
		 ;O azul é a cor dos patches restantes.
	]
        

  ;Variável dos patches. Se os patches representados pertencerem
  ;ao objecto que se pretende calcular a dimensão
  ;os patches representantes (em cada partição) têm pintado
  ;diferente de zero, caso contrário têm pintado igual a
  ;zero tal como todos os patches não representantes.
patches-own [ pintado ]
Funções principais
calculadimensao

Esta função é executada quando se premi o botão "Calcula Dimensão". Inicializa o gráfico e todas as variáveis. De seguida calcula o número de quadrados pintados para cada vez menores comprimentos do lado, marcando os pontos obtidos no gráfico em cada ciclo.

Mediante a escolha do utilizador (ver-particao), mostra para cada iteração os quadrados que verificou conterem células pintadas no seu interior, pintando esses de verde e os quadrados vazios de azul.

No final traça a tangente aproximada aos pontos marcados no gráfico.

to calculadimensao   ;Esta função é executada quando se pressiona Calcula Dimensão.
  locals [ 
          n       ;Variável auxiliar que indica o número de pontos que se pretende desenhar no gráfico.  
          rx ry   ;Variáveis auxiliares que tomam os valores das coordenadas dos patches representantes.
         ]
  reset-timer     ;Inicializa o contador interno da linguagen a zero e começa a contar o tempo.
  set verde (green + 0.1);
  set azul (blue + 0.1)  ;;definição das novas cores
  set porta true  ;Fica com este valor lógico até indicação contrária do utilizador, aí o programa aborta.
  inicializa-grafico 
  ifelse passo = 0 

      ;Se passo = 0, então coloca só um ponto no gráfico. 
      ;Isto é, só executa os cálculos para uma partição da janela,
      ;especificada pela variável lado (= tamanho do quadrado da particão).                     
    [ set n 1 ]
      ;Se passo diferente de 0, então calcula-o.
    [ set n int (lado / passo) ]


   ;Far-se-á n partições da janela gráfica.
 ;repeat n
 set lado 256
 repeat 9
    [
       ;A cada nova partição é necessário "limpar" todos os representantes, 
       ;pois eles são diferentes de particão para partição.
     ask patches [ set pintado 0 ]

       ;Cada patch calcula o seu representante. Se o patch pertence ao objecto
       ;para o qual se pretende saber a dimensão, então incrementa a variável
       ;"pintado" do seu representante uma unidade. 
     ask patches [ representantes ]
                                   
       ;Permite ao utilizador ver as sucessivas partições da janela
       ;e a aproximação (por quadrados) do objecto. 
     if ver-particao
       [
         ask patches [
                        ;Como cada patch calcula o seu representante.
                      set rx lado * int ((pxcor + screen-edge-x) / lado) - screen-edge-x 
                      set ry lado * int ((pycor + screen-edge-y) / lado) - screen-edge-y 
                        ;Se o representante está "pintado" então os representados fazem parte da 
                      ifelse (pintado-of patch rx ry != 0)
			[ 
                           ;aproximação e devem colorir-se de verde.
                         if pcolor = black or pcolor = azul
                           [ set pcolor verde ]
			]
                           ;Caso o representante não esteja pintado então o patch
			   ;sabe que não faz parte da aproximação, fica azul
                        [ set pcolor azul ]
                     ]                     
       ]
       ;O número de células com pintado != 0 é inicializado a zero em cada novo valor do lado  
     set NP 0
     ask patches [
       ;Contar o número de patches com pintado != 0, isto é, o número de representantes "pintados".
                  if pintado > 0 
                    [ set NP NP + 1 ]
		 ]

       ;Desenha um novo ponto no gráfico. 
     desenha-ponto
     ;set lado (lado - passo) ;Actualizar o lado.
     set lado lado / 2 

       ;Caso o utilizador tenha pressionado Parar, o programa acaba aqui.     
     if not porta
       [ set tempo timer stop ]
    ]
  ;set lado (lado + passo)
  set lado lado * 2  
  
    ;Traça a recta que passa no ponto (0.0) e no ponto do gráfico
    ;que corresponde ao menor valor de lado usado. 
    ;Calcula a dimensão fractal com base do declive na recta anterior.
  tangente
            
  set tempo timer ;Dá o tempo de cálculo.
end
Funções Auxiliares
inicializa-grafico

Função que apenas inicializa e traça as rectas correspondentes às dimensões 1 e 2

to inicializa-grafico ;Desenha duas rectas de enquadramento
  set-current-plot "Dimensao"
  set-current-plot-pen "dimensao 1"
  auto-plot-off
  plotxy 0 0
  plotxy 10 10
  set-current-plot-pen "dimensao 2"
  plotxy 0 0
  plotxy 10 5
  auto-plot-on
end
representantes

Função que calcula o representante da célula que a executou, e caso verifique que a célula está pintada, incrementa a propriedade pintado do seu representante

to representantes
  locals [ rx ry ]

    ;Como cada patch calcula as coordenadas do seu representante.
  set rx lado * int ((pxcor + screen-edge-x) / lado) - screen-edge-x
  set ry lado * int ((pycor + screen-edge-y) / lado) - screen-edge-y

    ;Se o patch respectivo pertence ao objecto então incrementa a variável  
    ;pintado do seu representante de uma unidade.
  if pcolor != black and pcolor != azul and pcolor != verde
    [ set (pintado-of patch rx ry) (pintado-of patch rx ry) + 1 ]
end
desenha-ponto

Função que marca um ponto no gráfico utilizando o valor das variáveis lado e NP (Número Pintado).

  ;Desenha um ponto no gráfico com os valores que variáveis globais (NP e lado)
  ;tenham no momento em que é chamada. 
to desenha-ponto
  set-current-plot "Dimensao"
  set-current-plot-pen "pontos"
  if NP = 0  
    [
     user-message "Não desenhou nada!"
     stop
    ] 

    ;Toma-se como unidade de comprimento a largura da janela. 
  if NP != 1
    [
     plotxy (1 / (- ln (lado / screen-size-x))) (1 / ln NP) 
    ]
end
tangente

Função que traça no gráfico a recta tangente aos pontos calculados

  ;Traça a recta que passa no ponto (0.0) e no ponto do
  ;gráfico que corresponde ao menor valor de lado usado. 

  ;Calcula a dimensão fractal com base do declive na recta anterior.
to tangente
  set-current-plot "Dimensao"
  set-current-plot-pen "tangente"
  auto-plot-off
  plotxy 0 0
  plotxy (100 * (1 / (- ln (lado / screen-size-x)))) (100 * (1 / ln NP))
  auto-plot-on
  show "Dimensão fractal: " + (ln NP / (- ln (lado / screen-size-x)))
end
apagar

Função que limpa e inicializa as variáveis do programa

to apagar 
   clear-all
end
desenhar

Função que é executada quando o utilizador prime o botão "desenhar", permite o utilizador acrescentar pontos no gráfico

to desenhar
if mouse-down?
  [ 
   set pcolor-of patch-at mouse-xcor mouse-ycor green
   ask patches-from patches with[pcolor = green] [patches in-radius-nowrap raio] [set pcolor red]  
  ]
end
parar

Função que avisa a função calculadimensao que o utilizador pretende parar o cálculo

to parar 
  set porta false
end
importarmundo

Função que executada quando o utilizador prime o botão com o mesmo nome, mostra uma janela onde o utilizador escolhe um ficheiro gerado anteriormente por outro modelo de fractais

  ;Permite importar um "mundo" de outro programa. Ignore eventuais mensagens
  ;de erro envolvendo variáveis globais.
to importarmundo
  locals[nomeficheiro]
  set nomeficheiro user-choose-file

    ;Caso o utilizador cancele a escolha de um ficheiro evita dar erro.
    ;Mas dá erro se o utilizador indicar um ficheiro inexistente no sistema.
  if nomeficheiro = false
    [ user-message "Abortou" stop ]
  import-world nomeficheiro
end
Início

Variantes e Extensões

Adapte o progrma de maneira permitir fazer o refinamento da partição de maneira aritmética, em vez de geométrica. Use esta variante para explorar com mais pontos a região das partições finas que serviu de base à estimativa da dimensão fractal nos exemplos que calculou antes.

Adapte o programa por forma a permitir outro tipo de recobrimentos, por exemplo por discos em vez de quadrados, e compare os resultados obtidos.

Início