UA-60303699-2 TP1 | Computação Gráfica e Interfaces 2016-2017

Trabalho Prático 1

Prazo de entrega: 23h59 de 15/10/2016

Introdução

Fractais

Fractais são estruturas que se repetem indefinidamente independentemente da escala usada e tanto podem ser resultado de fenómenos naturais ou de propriedades de conjuntos matemáticos.

Mandelbrot

Benoit Mandelbrot foi um matemático de origem polaca que se dedicou ao estudo de fractais enquanto professor visitante na Universidade de Harvard. Os conjuntos de Julia são conjuntos obtidos aplicando um função racional sobre o domínio dos números complexos, com resultado neste mesmo conjunto. Os conjuntos são formados por pontos que têm um mesmo comportamento no que à função racional diz respeito e foram introduzidos por Gaston Julia. Durante o estudo, Mandelbrot descobriu o conjunto atualmente conhecido por conjunto de Mandelbrot e que está fortemente relacionado com os conjuntos de Julia.

Eis alguns exemplos de visualização destes conjuntos:

Fractal-1 Fractal-2 Fractal-3 Fractal-4

Função fractal

Dados dois números complexos z0 e c, definimos a sequência z1, z2, z3, ..., zn, aplicando a seguinte função:

f(z) = z*z + c

iterativamente.

Assim, z1 = f(z0), z2=f(z1), ..., zn=f(zn-1)

Note-se que * é o produto de dois números complexos.

Duas coisas podem acontecer:

  • zn está limitado
  • zn não está limitado

Na prática a determinação se zn é ilimitado é difícil pois pode ocorrer ao fim de muitas iterações. Felizmente, assim que sqrt(z)>2, então zn será ilimitado.

Quando se procede à visualização destes conjuntos, o que se faz é avaliar a função fractal no plano dos números complexos e, para cada ponto do plano, verificar, até um número máximo de iterações, quantas iterações são necessárias até se concluir que a função se vai tornar ilimitada para esse ponto. Eis o pseudo código da função fractal:

int fractal(complex z0, complex c, int maxiterations) {
    complex z = z0
    for(int i=0; i<maxiterations; i++) {
        z = z*z + c
        if(re(z)*re(z) + im(z)*im(z) > 4) 
            break;
    }
    
    if( i==maxiterations) return 0;
    else return i;
}

Repare-se que a função acima devolve o número de iterações. Resta agora traduzir esse número para uma cor. Eis um exemplo duma função GLSL que produz cores interessantes:

vec3 paletize(float v, float factor) {
    float vv = v*factor;
    return vec3(sin(vv/3.0), cos(vv/6.0), cos(vv/(12.0+3.14/4.0)));
}

Nesta função usa-se ainda um valor (factor) que permite controlar a variação das cores.

O conjunto de Mandelbrot

O conjunto de Mandelbrot é o conjunto dos números complexos para os quais, a função fractal acima definida, com z0=0+0i, produz valores ilimitados. Neste caso o número complexo c representa o ponto onde queremos avaliar a função. Na visualização, os pontos do conjunto aparecerão a preto, visto a função retornar 0 nesses casos. Na vizinhança desse conjunto é onde as coisas se tornam interessantes...

Conjunto Mandelbrot
Conjunto Mandelbrot

Os conjuntos de Julia

Os conjuntos de Julia podem ser obtidos por fixação do valor de c e fazendo com que z0 seja o ponto do plano onde pretendemos avaliar a função fractal. Eis alguns exemplos interessantes de conjuntos de Julia:

Conjunto Julia para c=-0.4+0.6i
Conjunto Julia para c=-0.4+0.6i
Conjunto Julia para c=0.285+0i
Conjunto Julia para c=0.285+0i
Conjunto Julia para c=0.285+0.01i
Conjunto Julia para c=0.285+0.01i
Conjunto Julia para c=-0.8+0.156i
Conjunto Julia para c=-0.8+0.156i
Conjunto Julia para c=0.8+0i
Conjunto Julia para c=0.8+0i

Projeto

Pretende-se construir uma aplicação interativa que permita visualizar e explorar fractais. Cada pixel do canvas terá associada uma cor que resulta do mapeamento do valor da função fractal numa cor.

O programa deverá permitir ajustar os seguintes parâmetros:

  • centro center: permite definir o ponto do plano dos números complexos que será mostrado no centro do canvas. Inicialmente será 0+0i. A operação deverá ser por arrasto (drag) sobre o canvas. A imagem deverá deslocar-se solidária com o movimento do ponteiro do rato.
  • escala scale: permite definir qual a dimensão do plano dos números complexos a visualizar no canvas. Inicialmente deverá ser 1, resultando na visualização do subconjunto dos números complexos p: -1 <= re(p) <= 1 e -1 <= im(p) <= 1, ou seja um quadrado de lado 2.
  • factor factor: permite ajustar o valor retornado pela função fractal antes de a mapear numa cor, multiplicando-a por factor.
  • Escolher entre Visualização do conjunto de Mandelbrot e um conjunto de Julia
  • Opção Escolher de entre os vários conjuntos de Julia sugeridos atrás em vez apenas um deles.

Eis um pequeno video que demonstra o funcionamento da aplicação que se pretende desenvolver.

Detalhes técnicos

Geometria a desenhar

A única primitiva a desenhar neste trabalho será um TRIANGLE_STRIP que cobrirá o espaço [-1,1]x[-1,1]. Todo o trabalho será executado ao nível do fragment shader. O papel do vertex shader nesta aplicação é mínimo.

Parâmetros/Variáveis obrigatórias do programa GLSL

Os parâmetros (variáveis uniform) necessários (e obrigatórios) neste programa são:

  • um factor factor (tipo float)
  • a escala scale (tipo float)
  • o número complexo center que estará no centro do canvas (ponto 2D)
  • um valor booleano indicando se o fractal é o conjunto de Mandelbrot ou um conjunto de Julia.
  • o valor c para c da função fractal, para o caso da visualização corresponder a um conjunto de Julia.

Embora a função fractal() seja a mesma para os dois tipos de visualização, a inicialização é diferente. No caso do fractal de Mandelbrot, a função fractal() acima representada será alimentada com z0=0+0i e c=p. Para o caso dos fractais de Julia, os parâmetros serão z0=p e c=cte. p representa o ponto do plano onde se pretende avaliar a função e o seu valor será diferente para cada pixel do canvas, de acordo com o valor da escala (scale) e do ponto central (center). Em cada instante o canvas mostrará sempre a avaliação das funções fractais para o intervalo [re(center)-1/scale, re(center)+1/scale]x[im(center)-1/scale,im(center)+1/scale]

Regras e Informação Adicional

Composição dos grupos

Os trabalhos práticos deverão ser realizados por grupos de 2 alunos dum mesmo turno prático. Qualquer exceção a esta regra, terá que ser devidamente justificada e autorizada pelo respetivo docente.

Entrega

A entrega do trabalho consiste em apenas dois ficheiros (.html + .js da aplicação). Não se esqueça de testar o seu trabalho numa pasta contendo apenas os ficheiros entregues, localizada ao mesmo nível que a pasta Common, contendo os ficheiros das bibliotecas disponibilizadas.

Os ficheiros entregues deverão fazer parte dum arquivo .zip (exclui-se qualquer outro formato de arquivo compactado) e cujo nome seguirá a seguinte convenção:

NNNNN-MMMMM-TP1.zip

onde NNNNN e MMMMM representam os números de aluno de cada um dos elementos do grupo.

Os trabalhos deverão ser entregues via a plataforma moodle, na página do curso:

https://moodle.fct.unl.pt/course/view.php?id=4582

Avaliação

Os trabalhos serão avaliados pelo respetivo docente das aulas práticas e discutidos com os respetivos alunos em data a definir oportunamente.