"Eintopf"-Fractals

Started by Theo Gottwald, April 13, 2024, 10:09:14 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

We can add the Barnsley fern fractal to the previous script to create more interesting and complex results. Here's an example program that combines the Koch snowflake fractal, the Sierpinski triangle, and the Barnsley fern fractal:
' Koch Snowflake Fractal with Sierpinski Triangle, Barnsley Fern, and Color
' Oxygen Basic, ConsoleG, OpenGL

#compact
%filename "koch_sierpinski_fern.exe"
'uses RTL64
% Title "Koch Snowflake Fractal with Sierpinski Triangle, Barnsley Fern, and Color"

'% WindowStyle WS_OVERLAPPEDWINDOW
'% Animated
'% ScaleUp
% PlaceCentral
% AnchorCentral

% shaders

uses consoleG

BeginScript

procedure drawLine(float x1, float y1, float x2, float y2, float r, float g, float b) {
    color(r, g, b);
    glBegin(GL_LINES);
    glVertex2f(x1, y1);
    glVertex2f(x2, y2);
    glEnd();
}

procedure koch(float x1, float y1, float x2, float y2, int level, float r, float g, float b) {
    if (level == 0) {
        drawLine(x1, y1, x2, y2, r, g, b);
        return;
    }

    float dx = x2 - x1;
    float dy = y2 - y1;
    float len = sqrt(dx*dx + dy*dy) / 3.0;
    float angle = atan2(dy, dx);

    float x3 = x1 + len * cos(angle);
    float y3 = y1 + len * sin(angle);
    float x4 = x3 + len * cos(angle + PI / 3.0);
    float y4 = y3 + len * sin(angle + PI / 3.0);
    float x5 = x2 - len * cos(angle);
    float y5 = y2 - len * sin(angle);

    koch(x1, y1, x3, y3, level-1, r, g, b);
    koch(x3, y3, x4, y4, level-1, g, b, r);
    koch(x4, y4, x5, y5, level-1, b, r, g);
    koch(x5, y5, x2, y2, level-1, r, g, b);

    if (level == 1) {
        drawLine(x3, y3, x4, y4, g, b, r);
        drawLine(x4, y4, x5, y5, b, r, g);
        drawLine(x5, y5, x3, y3, r, g, b);
    }
}

procedure sierpinski(float x1, float y1, float x2, float y2, float x3, float y3, int level, float r, float g, float b) {
    if (level == 0) {
        return;
    }

    float midX1 = x1 + 0.5 * (x2 - x1);
    float midY1 = y1 + 0.5 * (y2 - y1);
    float midX2 = x2 + 0.5 * (x3 - x2);
    float midY2 = y2 + 0.5 * (y3 - y2);
    float midX3 = x3 + 0.5 * (x1 - x3);
    float midY3 = y3 + 0.5 * (y1 - y3);

    sierpinski(x1, y1, midX1, midY1, midX3, midY3, level-1, r, g, b);
    sierpinski(x2, y2, midX2, midY2, midX1, midY1, level-1, g, b, r);
    sierpinski(x3, y3, midX3, midY3, midX2, midY2, level-1, b, r, g);

    if (level == 1) {
        drawLine(midX1, midY1, midX2, midY2, g, b, r);
        drawLine(midX2, midY2, midX3, midY3, b, r, g);
        drawLine(midX3, midY3, midX1, midY1, r, g, b);
    }
}

procedure fern(float x, float y, float a, float b, float c, float d) {
    float x1 = 0;
    float y1 = 0;
    float x2 = 0;
    float y2 = 0;
    float r = rnd();

    if (r < 0.01) {
        x1 = 0;
        y1 = 0.16 * y;
    } else if (r < 0.85) {
        x1 = a * x + b * y;
        y1 = c * x + d * y + 1.6;
    } else if (r < 0.92) {
        x1 = a * x - b * y;
        y1 = -c * x - d * y + 1.6;
    } else {
        x1 = 0;
        y1 = 0.85 * y;
    }

    x2 = x + x1;
    y2 = y + y1;

    drawLine(x, y, x2, y2, 0.0, 0.5, 0.0);

    fern(x2, y2, a, b, c, d);
}

procedure main() {
    cls();
    shading();

    float x1 = -0.5;
    float y1 = -0.5;
    float x2 = 0.5;
    float y2 = -0.5;
    float x3 = 0.0;
    float y3 = 0.5;
    int level = 4;

    koch(x1, y1, x2, y2, level, 1.0, 0.0, 0.0);
    koch(x2, y2, x3, y3, level, 0.0, 1.0, 0.0);
    koch(x3, y3, x1, y1, level, 0.0, 0.0, 1.0);

    sierpinski(x1, y1, x2, y2, x3, y3, level, 1.0, 0.0, 0.0);

    float a = 0.85;
    float b = 0.04;
    float c = -0.04;
    float d = 0.85;

    fern(0.0, 0.0, a, b, c, d);

    waitkey();
}

EndScript

In this version of the program, we've added the Barnsley fern fractal to the previous script that combined the Koch snowflake fractal and the Sierpinski triangle. The `fern` procedure uses a recursive algorithm to generate the Barnsley fern fractal, with different transformations applied based on a random number.

In the `main` procedure, we first draw the Koch snowflake fractal using the `koch` procedure with different colors for each side of the triangle. We then call the `sierpinski` procedure to create the Sierpinski triangle pattern inside the Koch snowflake, using the same colors as the corresponding sides of the snowflake. Finally, we call the `fern` procedure to create the Barnsley fern fractal at the center of the Sierpinski triangle.

When you run this program, you should see a Koch snowflake fractal with harmonious colors, a Sierpinski triangle pattern inside it, and a Barnsley fern fractal at the center of the Sierpinski triangle. You can experiment with different values of the `level` variable to create different variations of the fractal patterns.