EP1
Exercício Programa 1 (EP1): Visualização de Fractais
Data de entrega: Sábado, 22 de abril de 2023, até 23:59 h. Veja a política de desconto em caso de atraso.
O que entregar: Apenas o arquivo
fractais.js
contendo o seu código fonte.Leia o capítulo Fractais das nossas notas-de-aula para entender melhor a parte teórica sobre fractais.
Objetivos
Treinar a sua habilidade com o Canvas do HTML, com alguns recursos de interação, transformação de coordenadas e JavaScript.
Descrição
Você deverá implementar um programa para visualização de fractais. Seu programa deve desenhar os conjuntos Mandelbrot e Julia-Fatou, de forma interativa, como descrito nesse enunciado.
Os conjuntos de Mandelbrot e Julia-Fatou são definidos para o plano dos números complexos, onde cada coordenada (r,s) é equivalente ao número complexo r + si, onde i é a raiz quadrada de -1.
Seu programa fractais.js
em JavaScript deve rodar usando
o mesmo arquivo fractais.html
fornecido nesse enunciado.
Isso simplifica o que você precisa entregar nesse EP.
As dimensões width
e height
do
fractais_canvas
definidas no arquivo HTML são apenas
exemplos. O seu programa deve manter o id
fractais_canvas
e precisa funcionar com outras dimensões,
sempre exibindo o conjunto Mandebrot no topo e o de Julia-Fatou na parte
inferior, dividindo o canvas verticalmente em duas partes, como
ilustrado na figura abaixo.
Conjunto Mandelbrot
Essa janela (metade superior do canvas) deverá utilizar NCORES (ao
menos 9 como no esqueleto fractais.js
) cores de sua
preferência. O tamanho da janela é definido no arquivo
fractais.html
. Use tamanhos diferentes, menores, durante o
desenvolvimento. Ou seja, você pode editar esse arquivo. Lembre-se
também de testar com tamanhos maiores.
O desenho inicial do conjunto Mandelbrot deve mostrar a região retangular do plano complexo definido pelo canto LEFT_BOTTOM = (-2.2, -1.5) e canto oposto RIGHT_TOP = (0.8, 1.5). Você pode assumir que o sentido do eixo vertical é para baixo (como no canvas). O TOP portanto pode ficar ‘abaixo’ de BOTTOM na figura.
Conjunto Julia-Fatou
Essa janela (metade inferior do canvas) deverá mostrar o conjunto Julia-Fatou utilizando duas cores a sua escolha. A janela tem as mesmas dimensões em pixel reservada ao conjunto Mandelbrot.
A janela deve ser mapeada inicialmente para a região retangular do plano complexo de canto LEFT_BOTTOM = (-1.5, -1.5) e canto oposto RIGHT_TOP = (1.5, 1.5). Considere a constante complexa c = (-0.62, -0.44) para desenhar o conteúdo inicial da janela.
Operação:
O programa deve aceitar os seguintes comandos do teclados e mouse:
- Reset pela tecla ‘r’ (e também ‘R’): o canvas deve voltar a condição inicial dos conjuntos Mandelbrot e Julia-Fatou.
- Shift (código ASCII = 16): ao segurar a teclas
SHIFT
, usuáries podem selecionar um retângulo sobre a janela exibindo o conjunto Mandelbrot. Para isso usuáries devem clicar em um ponto inicial, arrastar o mouse e soltar o botão sobre um segundo ponto. Tudo isso segurando aSHIFT
. O retângulo define uma nova área do plano complexo a ser exibida, e seu programa deve atualizar a janela Mandelbrot para exibir o conteúdo do plano complexo do retângulo selecionado.- Observe que essa função deve funcionar independentemente da ordem em que o mouse é pressionado e solto (exemplo, canto inferior-esquerdo para superior-direito, ou superior-esquerdo para inferior-direito etc.).
- Novo c: sem apertar a
SHIFT
, um clique do mouse sobre um ponto no conjunto Mandelbrot seleciona um novo ponto complexo c. O seu programa deve atualizar o conjunto Julia-Fatou com esse novo valor. Nada deve ocorrer se o botão for pressionado sobre a janela de Julia-Fatou.
Dicas
Considere a constante MAX_ITER = 100.
Como desenhar a imagem de Julia-Fatou:
- Primeiramente, mapeie os pixels (x,y) de coordenadas inteiras para as coordenadas do plano complexo z = (a,b).
- A seguir rode a iteração z = z2 + c até que |z| ≥ 2.
- Para evitar vários cálculos de raiz quadrada, use a condição z2 ≥ 4. Nesse caso, pinte o pixel como BACKGROUND.
- Caso, após
MAX_ITER
iterações, a condição z2 ≥ 4 não for satisfeita, considere que o pixel é de FOREGROUND.
Como desenhar a imagem do conjunto de Mandelbrot:
- Comece com um mapeamento semelhante ao do conjunto de Julia, mapeando os pixels da janela para o “retângulo” (região) no plano complexo sendo observado. Lembre-se que esse retângulo pode ser redefinido pelo usuário.
- Seja d o ponto complexo correspondente a um pixel dentro da janela Mandelbrot.
- Faça z = (0,0) e aplique a
transformação z = z2 + d
até que z2 ≥ 4 ou
até que
MAX_ITER
iterações sejam feitas. - Caso o programa terminar antes de
MAX_ITER
iterações, defina k como o número de iterações; - caso contrário defina k = 0.
- Finalmente pinte o pixel correspondente com
CORES[k % NCORES]
, ondeCORES
é um array de cores.
Desenvolvimento por etapas: Programas que não rodarem corretamente receberão uma nota baixa. Recomendamos portanto que você desenvolva o projeto segundo as seguintes etapas:
- Desenhe o conjunto inicial de Julia-Fatou.
- Desenhe o conjunto de Mandelbrot.
- Adicione os comandos do teclado.
- Adicione o botão esquerdo para seleção de c.
- Adicione a seleção do retângulo no conjunto Mandelbrot.
Lembre-se de colocar mensagens de depuração no
console.log
do JavaScript.
- Não deixe para a última hora: Comece seu trabalho logo e não esqueça de documentá-lo. Traga suas dúvidas para discutir em aula.
Arquivos
fractais.html
e fractais.js
Os esqueletos desses arquivos você encontra aqui.
Você deve utilizar o seguinte arquivo HTML para testar o seu programa
fractais.js
. Você pode salvar esse conteúdo em um arquivo
index.html
ou fractais.html
, apenas não altere
o src=fractais.js
e id="fractais_canvas"
.
<!doctype html>
<html lang="pt-br">
<head>
<meta charset="utf-8">
<title>EP01 Visualizador de Fractais</title>
<style>
canvas {border: 2px solid black;
}</style>
<script src="fractais.js" defer></script>
</head>
<body>
<canvas id="fractais_canvas" width="400" height="800"></canvas>
</body>
</html>
Com esse arquivo e o esqueleto fractais.js
abaixo (salve
necessariamente em um arquivo de nome “fractais.js”) você verá a borda
do canvas. Veja também a mensagem no console do JavaScript em seu
navegador.
Não esqueça de preencher o seu nome e número USP no cabeçalho.
/* ==================================================
fractais.js
Nome:
NUSP:
Ao preencher esse cabeçalho com o meu nome e o meu número USP,
declaro que todas as partes originais desse exercício programa (EP)
foram desenvolvidas e implementadas por mim e que portanto não
constituem desonestidade acadêmica ou plágio.
Declaro também que sou responsável por todas as cópias desse
programa e que não distribui ou facilitei a sua distribuição.
Estou ciente que os casos de plágio e desonestidade acadêmica
serão tratados segundo os critérios divulgados na página da
disciplina.
Entendo que EPs sem assinatura devem receber nota zero e, ainda
assim, poderão ser punidos por desonestidade acadêmica.
Abaixo descreva qualquer ajuda que você recebeu para fazer este
EP. Inclua qualquer ajuda recebida por pessoas (inclusive
monitores e colegas). Com exceção de material da disciplina, caso
você tenha utilizado alguma informação, trecho de código,...
indique esse fato abaixo para que o seu programa não seja
considerado plágio ou irregular.
Exemplo:
A minha função quicksort() foi baseada na descrição encontrada na
página https://www.ime.usp.br/~pf/algoritmos/aulas/quick.html.
Descrição de ajuda ou indicação de fonte:
================================================== */
// A `main()` só deve ser executada quando tudo estiver carregado
window.onload = main;
// --------------------------------------------------------
// Você pode usar essas constantes se desejar
const DEBUG = true;
const ITERATIONS = 100;
const DELTA = 4;
const SHIFT = 16; // código ASCII da tecla
// Condições iniciais de Julia e Mandelbrot
const CX = -0.62, CY = -0.44;
const JULIA_L = -1.5;
const JULIA_B = -1.5;
const JULIA_R = 1.5;
const JULIA_T = 1.5;
const MANDEL_L = -2.2;
const MANDEL_B = -1.5;
const MANDEL_R = 0.8;
const MANDEL_T = 1.5;
// Veja uma lista de cores em:
// https://www.w3schools.com/tags/ref_colornames.asp
const CORES = [
'black', 'magenta', 'red',
'orange', 'yellow', 'yellowgreen',
'green', 'blue', 'purple'
;
]
const NCORES = CORES.length;
// Variáveis globais
var gCanvas, gWidth, gHeith, gCtx;
// outra variáveis se desejar
/*
função main
*/
function main() {
= document.querySelector('#fractais_canvas');
gCanvas = gCanvas.width;
gWidth = gCanvas.height/2;
gHeight = gCanvas.getContext('2d');
gCtx
// use o console para colocar informações de depuração
// não se preocupe em remover os logs
= `Canvas tem tamanho ${gWidth} x ${2*gHeight}`;
msg console.log( msg );
// RESTO DA SUA FUNÇÃO MAIN
}
// outras funções
/*
FIM
*/
Opcional: Animação
Uma forma simples de gerar uma animação é interpolar valores entre dois números complexos C1 = r1 + js1 e C2 = r2 + js2. Seja nf o número de quadros da animação. Primeiramente, gere a imagem fractal usando C1. Para gerar o segundo quadro, incremente a parte real e imaginária usando um intervalo proporcial a nf. Por exemplo, Δr = (r2−r1)/nf. Para esse exercício, sua animação pode ser associada a um botão que, ao ser clicado mostra a animação. Você pode assumir que C1 e C2 são constantes, assim como nf ou, ainda, criar outros elementos na sua interface para modificar esses parâmetros.