§ Демо

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

§ Код

1#include <qblib.c>
2
3// Расчет фрактала
4int mandel(double cx, double cy) {
5
6    double x = 0, y = 0;
7    for (int i = 0; i < 256; i++) {
8
9        double tx = x*x - y*y + cx,
10               ty = 2*x*y     + cy;
11
12        x = tx;
13        y = ty;
14
15        if (x*x + y*y >= 4) return i;
16    }
17
18    return 255;
19}
20
21// Карта орбиты
22int orbit(double cx, double cy) {
23
24    double x = 0, y = 0;
25
26    for (int i = 160; i < 200; i++)
27    for (int j = 280; j < 320; j++) {
28        int cl = (qb_screen[j][i] >> 1);
29        pset(j, i, cl < 1 ? 1 : cl);
30    }
31    lineb(280,160,319,199,128);
32
33    for (int i = 0; i < 256; i++) {
34
35        double tx = x*x - y*y + cx,
36               ty = 2*x*y     + cy;
37
38        x = tx;
39        y = ty;
40
41        if (x*x + y*y >= 4) return i;
42
43        pset(300 + 5.0*x, 180 - 5.0*y, 255);
44    }
45
46    return 255;
47}
48
49int main(int argc, char* argv[]) {
50
51    screen(13);
52
53    for (int i = 1; i < 256; i++) palette(i, i, i, 128 + (i>>1));
54    palette(0, 0, 255, 0);
55
56    int     iter = 0;
57    double  x0 = 0, y0 = 0, f = 1.0;
58    int     mx = -1, my = -1;
59    double  dx = 0, dy = 0, df = 1;
60
61    while (sdlevent(EVT_REDRAW)) {
62
63        // Срабатывает событие
64        if (mx == mouse.x && my == mouse.y && mouse.st == 0 && iter == 0)
65            continue;
66
67        double xm = (float)(mx - 160) / 100.0;
68        double ym = (float)(100 - my) / 100.0;
69
70        // Процесс анимации закончен
71        if (iter == 0) {
72
73            // Нажата левая кнопка мышки
74            if (mouse.st & LF_CLICK ) {
75
76                iter = 25;
77                dx   = xm*f / (double) iter;
78                dy   = ym*f / (double) iter;
79                df   = pow(1.2, -1 / (float)iter);
80            }
81            // Отдаление
82            else if (mouse.st & RT_CLICK ) {
83
84                iter = 25;
85                dx   = xm*f / (float) iter;
86                dy   = ym*f / (float) iter;
87                df   = pow(2.0, 1 / (float)iter);
88            }
89
90        }
91
92        // Пропуск кадров если FPS просел
93        while (iter && sdl_trigger_frames > 0) {
94
95            x0 += dx;
96            y0 += dy;
97            f  *= df;
98
99            iter--;
100            sdl_trigger_frames--;
101        }
102
103        // Перерисовать фрактал
104        for (int y = -99;  y <= 100; y++)
105        for (int x = -160; x <  160; x++) {
106
107            double vx = x0 + f*(double)x / 100.0;
108            double vy = y0 + f*(double)y / 100.0;
109
110            int cl = mandel(vx, vy);
111            pset(160 + x, 100 - y, cl < 1 ? 1 : cl);
112        }
113
114        mx = mouse.x;
115        my = mouse.y;
116
117        // HUD
118        line(160, 98, 160, 102, 128);
119        line(158, 100, 162, 100, 128);
120
121        orbit(x0 + xm, y0 + ym);
122    }
123
124    return 0;
125}