Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
07d5a63435a6641b56c439a57dd1502fae40f3dc
[graphlib.git] / mandel / mandel.cpp
1 #include <DrawingWindow.h>
2 #include <QApplication>
3 #include <iostream>
4
5 // Fonction de dessin de l'ensemble de Madelbrot, dans la zone
6 // spécifiée, et avec la précision souhgaitée.
7 void do_mandel(DrawingWindow &w,
8                double Rmin, double Rmax, double Imin, double Imax,
9                int maxiter)
10 {
11     int x, y;                   // le pixel considéré
12     double cr, ci;              // le complexe correspondant
13     double zr, zi;              // pour calculer la suite
14     double zr2, zi2;            // zr^2 et zi^2
15     double pr, pi;              // taille d'un pixel
16     double rouge, vert, bleu;
17     int i;
18
19     pr = (Rmax - Rmin) / (w.width - 1);
20     pi = (Imax - Imin) / (w.height - 1);
21     
22     cr = Rmin;
23     for (x = 0; x < w.width; x++) {
24         ci = Imax;
25         for (y = 0; y < w.height; y++) {
26             // z_0 = 0
27             zr = zi = 0.0;
28             zr2 = zi2 = 0.0;
29             for (i = 0; zr2 + zi2 < 4 && i < maxiter; i++) {
30                 // on calcule le z suivant
31                 zi = 2 * zr * zi + ci;
32                 zr = zr2 - zi2 + cr;
33                 zr2 = zr * zr;
34                 zi2 = zi * zi;
35             }
36             if (i >= maxiter) {
37                 rouge = vert = bleu = 0.0;
38             } else {
39                 // on est sorti trop tôt du for(...): on affiche le
40                 // pixel d'un couleur en fonction de i
41                 int ii = (maxiter - 1 - i) % 96;
42                 if (ii < 32) {
43                     // vert -> bleu
44                     bleu = ii / 32.0;
45                     vert = 1.0 - bleu;
46                     rouge = 0.0;
47                 } else if (ii < 64) {
48                     // bleu -> rouge
49                     rouge = (ii - 32) / 32.0;
50                     bleu = 1.0 - rouge;
51                     vert = 0.0;
52                 } else {
53                     // rouge -> vert
54                     vert = (ii - 64) / 32.0;
55                     rouge = 1.0 - vert;
56                     bleu = 0.0;
57                 }
58             }
59             w.setColor(rouge, vert, bleu);
60             w.drawPoint(x, y);
61
62             ci -= pi;
63         }
64         cr += pr;
65     }
66 }
67
68 // Fonction de dessin principale, calcule la zone d'intérêt, appelle
69 // do_mandel(), pour dessiner l'ensemle, et permet le zoom.
70 void mandel(DrawingWindow &w)
71 {
72     // nombre max d'itérations
73     int maxiter = 500;
74     // zone d'intérêt par défaut
75     double Rmin = -2.05;
76     double Rmax = 0.55;
77     double Imin = -1.3;
78     double Imax = 1.3;
79     // cible du zoom
80     double Tr;
81     double Ti;
82
83     while (1) {
84         do_mandel(w, Rmin, Rmax, Imin, Imax, maxiter);
85
86         w.setColor("white");
87         w.drawText(5, 5, "Cliquer sur l'image pour zoomer");
88
89         int x, y;
90         int button;
91         w.waitMousePress(x, y, button);
92
93         // calcul des coordonnées du point cliqué
94         Tr = Rmin + x * (Rmax - Rmin) / (w.width - 1);
95         Ti = Imax - y * (Imax - Imin) / (w.height - 1);
96
97         // calcul de la nouvelle zone d'intérêt :
98         // zoom ×2 en direction du point cliqué
99         const int zoom = 2;
100         double Rmin2 = Rmin / zoom;
101         double Rmax2 = Rmax / zoom;
102         double Imin2 = Imin / zoom;
103         double Imax2 = Imax / zoom;
104         double Rshift = Tr - (Rmin2 + Rmax2) / 2;
105         double Ishift = Ti - (Imin2 + Imax2) / 2;
106         Rmin2 += Rshift;
107         Rmax2 += Rshift;
108         Imin2 += Ishift;
109         Imax2 += Ishift;
110
111         // affichage d'un rectangle autour de la nouvelle zone d'intérêt
112         double x_factor = (w.width - 1) / (Rmax - Rmin);
113         double y_factor = (w.height - 1) / (Imax - Imin);
114         w.setColor("white");
115         w.drawRect((Rmin2 - Rmin) * x_factor, (Imax - Imin2) * y_factor,
116                    (Rmax2 - Rmin) * x_factor, (Imax - Imax2) * y_factor);
117
118         Rmin = Rmin2;
119         Rmax = Rmax2;
120         Imin = Imin2;
121         Imax = Imax2;
122     }
123 }
124
125 int main(int argc, char *argv[])
126 {
127     QApplication app(argc, argv);
128     DrawingWindow win(mandel, 800, 800);
129     win.show();
130     return app.exec();
131 }