segunda-feira, 19 de maio de 2025

Fazendo fractais com o Scilab

 

Abaixo temos um código Scilab que gera os seguintes fractais: Conjunto de Mandelbrot, Conjunto de Julia, Curva de Koch (e Floco de Neve de Koch), Triângulo de Sierpinski, Tapete de Sierpinski e Curva do Dragão. Cada fractal será plotado em uma janela gráfica separada.

Código Scilab para Fractais:
/////  Alguns fractais.
close(winsid()); clc;

// 1. Conjunto de Mandelbrot
function mandelbrot(xmin, xmax, ymin, ymax, nx, ny, max_iter)
    x = linspace(xmin, xmax, nx);
    y = linspace(ymin, ymax, ny);
    [X, Y] = meshgrid(x, y);
    Z = X + %i * Y;
    C = Z;
    iter = zeros(nx, ny);
    for k = 1:max_iter
        Z = Z.^2 + C;
        mask = (abs(Z) > 2) & (iter == 0);
        iter(mask) = k;
    end
    scf(1);
    clf();
    grayplot(x, y, iter);
    title("Conjunto de Mandelbrot", "fontsize", 4);
    xlabel("Re", "fontsize", 3);
    ylabel("Im", "fontsize", 3);
    //colormap(jetcolormap(64));
endfunction

// 2. Conjunto de Julia
function julia(xmin, xmax, ymin, ymax, nx, ny, max_iter, c)
    x = linspace(xmin, xmax, nx);
    y = linspace(ymin, ymax, ny);
    [X, Y] = meshgrid(x, y);
    Z = X + %i * Y;
    iter = zeros(nx, ny);
    for k = 1:max_iter
        Z = Z.^2 + c;
        mask = (abs(Z) > 2) & (iter == 0);
        iter(mask) = k;
    end
    scf(2);
    clf();
    grayplot(x, y, iter);
    title("Conjunto de Julia (c = " + string(c) + ")", "fontsize", 4);
    xlabel("Re", "fontsize", 3);
    ylabel("Im", "fontsize", 3);
    //colormap(jetcolormap(64));
endfunction

// 3. Curva de Koch e Floco de Neve de Koch
function [x, y]=koch_curve(x1, y1, x2, y2, n)
    if n == 0 then
        x = [x1, x2];
        y = [y1, y2];
    else
        dx = (x2 - x1) / 3;
        dy = (y2 - y1) / 3;
        x3 = x1 + dx;
        y3 = y1 + dy;
        x5 = x2 - dx;
        y5 = y2 - dy;
        x4 = x3 + (x5 - x3) / 2 - (y5 - y3) * sqrt(3) / 2;
        y4 = y3 + (y5 - y3) / 2 + (x5 - x3) * sqrt(3) / 2;
        [xA, yA] = koch_curve(x1, y1, x3, y3, n-1);
        [xB, yB] = koch_curve(x3, y3, x4, y4, n-1);
        [xC, yC] = koch_curve(x4, y4, x5, y5, n-1);
        [xD, yD] = koch_curve(x5, y5, x2, y2, n-1);
        x = [xA(1:$-1), xB(1:$-1), xC(1:$-1), xD];
        y = [yA(1:$-1), yB(1:$-1), yC(1:$-1), yD];
    end
endfunction

function koch_snowflake(n)
    x1 = [0, 0.5, 1, 0];
    y1 = [0, sqrt(3)/2, 0, 0];
    [xA, yA] = koch_curve(x1(1), y1(1), x1(2), y1(2), n);
    [xB, yB] = koch_curve(x1(2), y1(2), x1(3), y1(3), n);
    [xC, yC] = koch_curve(x1(3), y1(3), x1(4), y1(4), n);
    x = [xA(1:$-1), xB(1:$-1), xC];
    y = [yA(1:$-1), yB(1:$-1), yC];
    scf(3);
    clf();
    plot(x, y, "b-");
    title("Floco de Neve de Koch (n = " + string(n) + ")", "fontsize", 4);
    xlabel("x", "fontsize", 3);
    ylabel("y", "fontsize", 3);
    xgrid();
    a = gca();
    a.isoview = "on";
endfunction

// 4. Triângulo de Sierpinski
function sierpinski_triangle(x1, y1, x2, y2, x3, y3, n)
    if n == 0 then
        plot([x1, x2, x3, x1], [y1, y2, y3, y1], "k-");
    else
        xm1 = (x1 + x2) / 2;
        ym1 = (y1 + y2) / 2;
        xm2 = (x2 + x3) / 2;
        ym2 = (y2 + y3) / 2;
        xm3 = (x3 + x1) / 2;
        ym3 = (y3 + y1) / 2;
        sierpinski_triangle(x1, y1, xm1, ym1, xm3, ym3, n-1);
        sierpinski_triangle(xm1, ym1, x2, y2, xm2, ym2, n-1);
        sierpinski_triangle(xm3, ym3, xm2, ym2, x3, y3, n-1);
    end
endfunction

function plot_sierpinski_triangle(n)
    scf(4);
    clf();
    sierpinski_triangle(0, 0, 1, 0, 0.5, sqrt(3)/2, n);
    title("Triângulo de Sierpinski (n = " + string(n) + ")", "fontsize", 4);
    xlabel("x", "fontsize", 3);
    ylabel("y", "fontsize", 3);
    xgrid();
    a = gca();
    a.isoview = "on";
endfunction

// 5. Tapete de Sierpinski
function sierpinski_carpet(x, y, len, n)
    if n == 0 then
        xrec = [x, x+len, x+len, x, x];
        yrec = [y, y, y+len, y+len, y];
        plot(xrec, yrec, "k-");
    else
        new_len = len / 3;
        for i = 0:2
            for j = 0:2
                if (i == 1) & (j == 1) then
                    continue;
                end
                sierpinski_carpet(x + i*new_len, y + j*new_len, new_len, n-1);
            end
        end
    end
endfunction

function plot_sierpinski_carpet(n)
    scf(5);
    clf();
    sierpinski_carpet(0, 0, 1, n);
    title("Tapete de Sierpinski (n = " + string(n) + ")", "fontsize", 4);
    xlabel("x", "fontsize", 3);
    ylabel("y", "fontsize", 3);
    xgrid();
    a = gca();
    a.isoview = "on";
endfunction

// 6. Curva do Dragão
function [x, y]=dragon_curve(x1, y1, x2, y2, n, direction)
    if n == 0 then
        x = [x1, x2];
        y = [y1, y2];
    else
        xm = (x1 + x2) / 2;
        ym = (y1 + y2) / 2;
        dx = (x2 - x1) / 2;
        dy = (y2 - y1) / 2;
        if direction == 1 then
            xn = xm + dy;
            yn = ym - dx;
        else
            xn = xm - dy;
            yn = ym + dx;
        end
        [xA, yA] = dragon_curve(x1, y1, xn, yn, n-1, 1);
        [xB, yB] = dragon_curve(x2, y2, xn, yn, n-1, -1);
        x = [xA(1:$-1), xB];
        y = [yA(1:$-1), yB];
    end
endfunction

function plot_dragon_curve(n)
    [x, y] = dragon_curve(0, 0, 1, 0, n, 1);
    scf(6);
    clf();
    plot(x, y, "r-");
    title("Curva do Dragão (n = " + string(n) + ")", "fontsize", 4);
    xlabel("x", "fontsize", 3);
    ylabel("y", "fontsize", 3);
    xgrid();
    a = gca();
    a.isoview = "on";
endfunction

// Executa todas as funções
// Conjunto de Mandelbrot
mandelbrot(-2, 1, -1.5, 1.5, 400, 400, 100);

// Conjunto de Julia (c = -0.4 + 0.6i)
julia(-1.5, 1.5, -1.5, 1.5, 400, 400, 100, -0.39 + 0.58*%i);

// Floco de Neve de Koch
koch_snowflake(5);

// Triângulo de Sierpinski
plot_sierpinski_triangle(5);

// Tapete de Sierpinski
plot_sierpinski_carpet(4);

// Curva do Dragão
plot_dragon_curve(15);
Explicação do Código
  1. Conjunto de Mandelbrot:
    • Usa a equação
      Z_{n+1} = Z_n^2 + C
      , com
      Z_0 = 0
      . Plota pontos que não divergem em preto, colorindo a fronteira com base no número de iterações até a divergência.
  2. Conjunto de Julia:
    • Similar ao Mandelbrot, mas fixa ( C ) (aqui,
      C = -0.4 + 0.6i
      ) e varia
      Z_0
      . O resultado mostra padrões intricados típicos do conjunto de Julia.
  3. Curva de Koch e Floco de Neve de Koch:
    • A função koch_curve divide cada segmento em três, adicionando um triângulo, e repete recursivamente. koch_snowflake conecta três curvas para formar o floco de neve.
  4. Triângulo de Sierpinski:
    • Divide recursivamente um triângulo em quatro menores, removendo o central. Plota os triângulos restantes, criando um padrão auto-similar.
  5. Tapete de Sierpinski:
    • Divide um quadrado em uma grade 3x3, remove o quadrado central, e repete o processo nos quadrados restantes. Plota os quadrados remanescentes.
  6. Curva do Dragão:
    • Divide cada segmento em dois, adicionando um vértice com rotação de 90 graus, alternando direções. O resultado é uma curva que preenche o espaço.
Resultados:
  • Janela 1: Conjunto de Mandelbrot, com a região preta e uma fronteira colorida (primeira figura desta postagem).
  • Janela 2: Conjunto de Julia, mostrando padrões intricados em torno do valor de ( C ).
  • Janela 3: Floco de Neve de Koch, uma figura azul simétrica com detalhes fractais.
  • Janela 4: Triângulo de Sierpinski, um triângulo preto com "buracos" auto-similares.
  • Janela 5: Tapete de Sierpinski, um quadrado preto com subquadrados removidos.
  • Janela 6: Curva do Dragão, uma linha vermelha que se dobra em ângulos retos. 

 


Nenhum comentário:

Postar um comentário