§ Демо

Есть еще материал по Мандельбротской демонстрации.
1c597194ae83e3490a32d5827484f695.png

§ Код

#include <qblib.c>

// Расчет фрактала
int mandel(double cx, double cy) {

    double x = 0, y = 0;
    for (int i = 0; i < 256; i++) {

        double tx = x*x - y*y + cx,
               ty = 2*x*y     + cy;

        x = tx;
        y = ty;

        if (x*x + y*y >= 4) return i;
    }

    return 255;
}

// Карта орбиты
int orbit(double cx, double cy) {

    double x = 0, y = 0;

    for (int i = 160; i < 200; i++)
    for (int j = 280; j < 320; j++) {
        int cl = (qb_screen[j][i] >> 1);
        pset(j, i, cl < 1 ? 1 : cl);
    }
    lineb(280,160,319,199,128);

    for (int i = 0; i < 256; i++) {

        double tx = x*x - y*y + cx,
               ty = 2*x*y     + cy;

        x = tx;
        y = ty;

        if (x*x + y*y >= 4) return i;

        pset(300 + 5.0*x, 180 - 5.0*y, 255);
    }

    return 255;
}

int main(int argc, char* argv[]) {

    screen(13);

    for (int i = 1; i < 256; i++) palette(i, i, i, 128 + (i>>1));
    palette(0, 0, 255, 0);

    int     iter = 0;
    double  x0 = 0, y0 = 0, f = 1.0;
    int     mx = -1, my = -1;
    double  dx = 0, dy = 0, df = 1;

    while (sdlevent(EVT_REDRAW)) {

        // Срабатывает событие
        if (mx == mouse.x && my == mouse.y && mouse.st == 0 && iter == 0)
            continue;

        double xm = (float)(mx - 160) / 100.0;
        double ym = (float)(100 - my) / 100.0;

        // Процесс анимации закончен
        if (iter == 0) {

            // Нажата левая кнопка мышки
            if (mouse.st & LF_CLICK ) {

                iter = 25;
                dx   = xm*f / (double) iter;
                dy   = ym*f / (double) iter;
                df   = pow(1.2, -1 / (float)iter);
            }
            // Отдаление
            else if (mouse.st & RT_CLICK ) {

                iter = 25;
                dx   = xm*f / (float) iter;
                dy   = ym*f / (float) iter;
                df   = pow(2.0, 1 / (float)iter);
            }

        }

        // Пропуск кадров если FPS просел
        while (iter && sdl_trigger_frames > 0) {

            x0 += dx;
            y0 += dy;
            f  *= df;

            iter--;
            sdl_trigger_frames--;
        }

        // Перерисовать фрактал
        for (int y = -99;  y <= 100; y++)
        for (int x = -160; x <  160; x++) {

            double vx = x0 + f*(double)x / 100.0;
            double vy = y0 + f*(double)y / 100.0;

            int cl = mandel(vx, vy);
            pset(160 + x, 100 - y, cl < 1 ? 1 : cl);
        }

        mx = mouse.x;
        my = mouse.y;

        // HUD
        line(160, 98, 160, 102, 128);
        line(158, 100, 162, 100, 128);

        orbit(x0 + xm, y0 + ym);
    }

    return 0;
}