Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
1afd6409d75c123e6eb9cc38f0e9b17713e5c825
[graphlib.git] / mandel / mandel.cpp
1 #include <DrawingWindow.h>
2 #include <QApplication>
3 #include <iostream>
4
5 void do_mandel(DrawingWindow &w,
6                double Rmin, double Rmax, double Imin, double Imax,
7                int maxiter)
8 {
9     int x, y;                   // le pixel considéré
10     double cr, ci;              // le complexe correspondant
11     double zr, zi;              // pour calculer la suite
12     double zr2, zi2;
13     double pr, pi;              // taille d'un pixel
14     double rouge, vert, bleu;
15     int i;
16
17     pr = (Rmax - Rmin) / (w.width - 1);
18     pi = (Imax - Imin) / (w.height - 1);
19     
20     cr = Rmin;
21     for (x = 0; x < w.width; x++) {
22         ci = Imax;
23         for (y = 0; y < w.height; y++) {
24             // z_1 = c
25             zr = cr;
26             zi = ci;
27             for (i = 1; i <= maxiter; i++) {
28                 zr2 = zr * zr;
29                 zi2 = zi * zi;
30                 if (zr2 + zi2 >= 4) {
31                     // |z| >= 2 : on sort de la boucle
32                     break;
33                 }
34                 // on calcule le z suivant
35                 zi = 2 * zr * zi + ci;
36                 zr = zr2 - zi2 + cr;
37             }
38             if (i > maxiter) {
39                 rouge = vert = bleu = 0.0;
40             } else {
41                 // on est sorti trop tôt du for(...): on affiche le
42                 // pixel d'un couleur en fonction de i
43                 int ii = (maxiter - i) % 96;
44                 if (ii < 32) {
45                     // vert -> bleu
46                     bleu = ii / 32.0;
47                     vert = 1.0 - bleu;
48                     rouge = 0.0;
49                 } else if (ii < 64) {
50                     // bleu -> rouge
51                     rouge = (ii - 32) / 32.0;
52                     bleu = 1.0 - rouge;
53                     vert = 0.0;
54                 } else {
55                     // rouge -> vert
56                     vert = (ii - 64) / 32.0;
57                     rouge = 1.0 - vert;
58                     bleu = 0.0;
59                 }
60             }
61             w.setColor(rouge, vert, bleu);
62             w.drawPoint(x, y);
63
64             ci -= pi;
65         }
66         cr += pr;
67     }
68 }
69
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 }