Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Ooops.
[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;
18     pi = (Imax - Imin) / w.height;
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 pixel
42                    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         std::cout << "[ " << Rmin
85                   << (Imin >= 0.0 ? " + " : " - ")
86                   << (Imin >= 0.0 ? Imin : -Imin)
87                   << " i ; " << Rmax
88                   << (Imax >= 0.0 ? " + " : " - ")
89                   << (Imax >= 0.0 ? Imax : -Imax)
90                   << " i ] (" << maxiter << ")"
91                   << std::endl;
92
93         do_mandel(w, Rmin, Rmax, Imin, Imax, maxiter);
94
95         int x, y;
96         int button;
97         std::cout << "-=[ Cliquer sur l'image pour zoomer ]=-" << std::endl;
98         w.waitMousePress(x, y, button);
99         Tr = Rmin + x * (Rmax - Rmin) / w.width;
100         Ti = Imax - y * (Imax - Imin) / w.height;
101         std::cout << "(" << x << ";" << y << ") -> ("        
102                   << Tr << ";" << Ti << ")" << std::endl;
103
104         double Rmin2 = Rmin / 2;
105         double Rmax2 = Rmax / 2;
106         double Imin2 = Imin / 2;
107         double Imax2 = Imax / 2;
108         double Rdecal = Tr - (Rmin2 + Rmax2) / 2;
109         double Idecal = Ti - (Imin2 + Imax2) / 2;
110         Rmin2 += Rdecal;
111         Rmax2 += Rdecal;
112         Imin2 += Idecal;
113         Imax2 += Idecal;
114
115         double x_factor = w.width / (Rmax - Rmin);
116         double y_factor = w.height / (Imax - Imin);
117         w.setColor("white");
118         w.drawRect((Rmin2 - Rmin) * x_factor, (Imax - Imin2) * y_factor,
119                    (Rmax2 - Rmin) * x_factor, (Imax - Imax2) * y_factor);
120
121         Rmin = Rmin2;
122         Rmax = Rmax2;
123         Imin = Imin2;
124         Imax = Imax2;
125     }
126 }
127
128 int main(int argc, char *argv[])
129 {
130     QApplication app(argc, argv);
131     DrawingWindow win(mandel, 800, 800);
132     win.show();
133     return app.exec();
134 }