Welcome to Fractal Forums

Community => Meet & Greet => Topic started by: stigomaster on July 17, 2009, 07:05:47 PM




Title: Another greeting from Oslo, Norway
Post by: stigomaster on July 17, 2009, 07:05:47 PM
Hello, my name is Stig, I`m from Oslo and I`m 16 in August. Fractals are very cool indeed, and I`ve kept a little eye on a 3D mandelbrot forum here before I decided to join.
And hey, I wrote this program in two days using C++ and Allegro. It`s the good old Mandelbrot set, which allows you to zoom with the mouse, reset with `R` if you get lost and even terminate the program with Esc! *proud* I will keep experimenting with the program, but I felt like displaying it right now to show off my 1337 fractal skills.

Code:
#include <allegro.h>
#include <math.h>

using namespace std;

int mandel(int iterations, double bailout, double cr, double ci);

int main() {
    allegro_init();
    set_color_depth(8);
    if(set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)) {
        allegro_message(allegro_error);
        return 1;
    }
    install_keyboard();
    install_mouse();
   
    int iterations = 600;
    double bailout = 50.0;   
    double r1 = -2.5;
    double i1 = -1.5;
    double r2 = 1.5;
    double i2 = 1.5;   
    double cr, ci = 0;
    double width = r2 - r1;
    double height = i2 - i1;   
    double rIncr = width / SCREEN_W;
    double iIncr = height / SCREEN_H;
    int x, y = 0;   
    int col = 0;
    bool mainLoop = true;
    bool inputLoop = true;
   
    BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
   
    show_mouse(screen);
   
    while(mainLoop) {
        scare_mouse();
        inputLoop = true;
        ci = i1;
        for(y = 0; y < SCREEN_H; y++) {
            ci += iIncr;
            cr = r1;
            for(x = 0; x < SCREEN_W; x++) {
                cr += rIncr;
                col = mandel(iterations, bailout, cr, ci) % 256;
                putpixel(buffer, x, y, col);
            }
            if(!(y % 48)) blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
        }
        blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
        unscare_mouse();
        while(inputLoop) {
            if(key[KEY_ESC]) {
                mainLoop = false;
                inputLoop = false;
            }
            if(mouse_b & 1) {
                cr = fabs(mouse_x) / SCREEN_W * width + r1;
                ci = fabs(mouse_y) / SCREEN_H * height + i1;
                r1 = cr - width / 8.0;
                i1 = ci - height / 8.0;
                r2 = cr + width / 8.0;
                i2 = ci + height / 8.0;
                width = r2 - r1;
                height = i2 - i1;
                rIncr = width / SCREEN_W;
                iIncr = height / SCREEN_H;               
                inputLoop = false;
            }
            if(key[KEY_R]) {
                r1 = -2.5;
                i1 = -1.5;
                r2 = 1.5;
                i2 = 1.5;               
                width = r2 - r1;
                height = i2 - i1;
                rIncr = width / SCREEN_W;
                iIncr = height / SCREEN_H;               
                inputLoop = false;
            }
        }
    }
    destroy_bitmap(buffer);
    allegro_exit();   
    return 0;
}
END_OF_MAIN()

int mandel(int iterations, double bailout, double cr, double ci) {
    double sqrBail = bailout * bailout;
    double zr, zi = 0.0;
    double zr_n, zi_n = 0.0;
    int iterCounter = 0;
    double dist = cr * cr + ci * ci;
    while(dist < sqrBail && iterCounter < iterations) {
        zr_n = (zr * zr) - (zi * zi);
        zi_n = 2 * zr * zi;
        zr = zr_n + cr;
        zi = zi_n + ci;
        dist = (zr * zr) + (zi * zi);
        iterCounter++;
    }
    return iterCounter % iterations;
}

Well, sorry for not bothering to add comments to the code, but I _hope_ it's pretty self-documenting. This is actually a re-write, 'cause I first wrote it on another pc without having brought a memory stick  :P


Title: Re: Another greeting from Oslo, Norway
Post by: cKleinhuis on July 17, 2009, 08:41:09 PM
hi there, and welcome to the forum, great to see young people are still learning to code :D

so, here is a little goodie you could try out:

alternating fractal:

 in your while loop, make a switch statement like:

switch(iterCounter%2){

case 0:
        // Classic mandelbrot formula fn+1=z^2+c
        zr_n = (zr * zr) - (zi * zi);
        zi_n = 2 * zr * zi;
        zr = zr_n + cr;
        zi = zi_n + ci;
break;
case 1:
    // and here another formula, you can easily change ANY formula part here,
// e.g. switch cr/ci ... replace 2 by 3 :D ... and look what happens :D
        zr_n = (zr * zr) - (zi * zi);
        zi_n = 2 * zr * zi;
        zr = zr_n + cr;
        zi = zi_n + ci;
break;
}

ok, thats just for little exploring the fractal world ... when i first used this method i used an array of seeds e.g. cr[2] ci[2] and swapped them whilst using the same formulas in each
switch case ....


so, and one last hint ... try using a structure for saving the complex values, or even better, use the in c++ standard library complex.h headers and
write the formula simply as znew=zold*zold+seed

cheers
ck

 :police: :police: :police: O0


Title: Re: Another greeting from Oslo, Norway
Post by: stigomaster on July 17, 2009, 09:13:38 PM
Yeah, I know I can use a library to ease the complex math, but I wanted to do it myself to make sure I really understood the math. When I first tried the program, I only got a weird diamond-shaped figure. I found out that I had confused a + for a -, so the code read "zr_n = (zr * zr) + (zi * zi);"
But hey, mistakes is what you learn from, right? I learned something new because I didn't use a library.  :)


Title: Re: Another greeting from Oslo, Norway
Post by: stigomaster on July 17, 2009, 09:22:34 PM
And by the way, I have already experimented with the formula, just not by a switch, but by a changing code and then rebuilding. I've tried replacing the 2 by a 3, (and even by decimal values), and using things such as changing the "dist =". "dist = zr * zr / zi" was particularly interesting, as hyperbolas appeared everywhere, even inside the M-set! I'm trying what you suggested now, thanks.


Title: Re: Another greeting from Oslo, Norway
Post by: David Makin on July 17, 2009, 09:43:08 PM
Just to mention that I notice you're using delta values to step across and down the screen - if you want to zoom deeper then you should replace this method with explicit calculation of yvalue=ybase+ypixel*ystep in each y loop and xvalue = xbase+xpixel*xstep in each x loop - I realise that's (slightly) slower but it will give considerably more scope for deeper zooming (my old 32-bit DOS fractal program MMFrac did the same thing and I never got around to changing it).
Also there's a good optimisation you can make for the standard Mandelbrot/Julia and any other fractal formulas that need the values of x^2 and y^2 in the fractal formula calculation - at the end of each iteration when testing for bailout store the values of x^2 and y^2 and use those in the next loop instead of recalculating them - that optimisation will actually save considerably more time than is added by the above change in step calculation :)


Title: Re: Another greeting from Oslo, Norway
Post by: Nahee_Enterprises on January 01, 2010, 12:48:00 AM
   Hello, my name is Stig, I`m from Oslo and I`m 16 in August.   Fractals are very cool indeed, and I`ve kept a
    little eye on a 3D mandelbrot forum here before I decided to join.   And hey, I wrote this program in two
    days using C++ and Allegro.   It`s the good old Mandelbrot set, which allows you to zoom with the mouse,
    reset with `R` if you get lost and even terminate the program with Esc! *proud*   I will keep experimenting
    with the program, but I felt like displaying it right now to show off my 1337 fractal skills.

Greetings, and a very late Welcome to this particular Forum !!!     :D

Keep up the good work with your programing and learning.