Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Cosmetics.
[graphlib_java.git] / MoreEx / Mandel.java
1 class Mandel {
2
3     static class Parameters {
4         // nombre max d'itérations
5         int maxiter;
6         // zone d'intérêt par défaut
7         double Rmin;
8         double Rmax;
9         double Imin;
10         double Imax;
11         // facteur d'échelle
12         double Rscale;
13         double Iscale;
14     }
15
16     static final Parameters initial_parameters;
17     static {
18         initial_parameters = new Parameters();
19         initial_parameters.maxiter = 1000;
20         initial_parameters.Rmin    = -2.05;
21         initial_parameters.Rmax    = 0.55;
22         initial_parameters.Imin    = -1.3;
23         initial_parameters.Imax    = 1.3;
24         initial_parameters.Rscale  = 0.0;
25         initial_parameters.Iscale  = 0.0;
26     }
27
28     static double sqr(double x)
29     {
30         return x * x;
31     }
32
33     static int check_point(Parameters p, double cr, double ci)
34     {
35         double zr2, zi2;
36         zi2 = sqr(ci);
37         if (sqr(cr + 1) + zi2 < 1.0 / 16.0)
38             return p.maxiter;
39         double x4 = cr - 1.0 / 4.0;
40         double q = sqr(x4) + zi2;
41         if (q * (q + x4) < zi2 / 4.0)
42             return p.maxiter;
43         zr2 = sqr(cr);
44         double zr = cr;
45         double zi = ci;
46         int i;
47         for (i = 0 ; i < p.maxiter && zr2 + zi2 < 4 ; i++) {
48             zi = 2 * zr * zi + ci;
49             zr = zr2 - zi2 + cr;
50             zr2 = sqr(zr);
51             zi2 = sqr(zi);
52         }
53         return i;
54     }
55
56     static void set_color(DrawingWindow w, Parameters p, int i)
57     {
58         float rouge, vert, bleu;
59         if (i >= p.maxiter) {
60             rouge = vert = bleu = 0.0f;
61         } else {
62             int ii = (p.maxiter - 1 - i) % 96;
63             if (ii < 32) {
64                 // vert -> bleu
65                 bleu = ii / 32.0f;
66                 vert = 1.0f - bleu;
67                 rouge = 0.0f;
68             } else if (ii < 64) {
69                 // bleu -> rouge
70                 rouge = (ii - 32) / 32.0f;
71                 bleu = 1.0f - rouge;
72                 vert = 0.0f;
73             } else {
74                 // rouge -> vert
75                 vert = (ii - 64) / 32.0f;
76                 rouge = 1.0f - vert;
77                 bleu = 0.0f;
78             }
79         }
80         w.setColor(rouge, vert, bleu);
81     }
82
83     // Fonction de dessin de l'ensemble de Madelbrot, dans la zone
84     // spécifiée, et avec la précision souhgaitée.
85     static void do_mandel(DrawingWindow w, Parameters p)
86     {
87         int x, y;                   // le pixel considéré
88         double cr, ci;              // le complexe correspondant
89         for (y = 0 ; y < w.height ; y++) {
90             ci = p.Imax - y * p.Iscale;
91             cr = p.Rmin;
92             int x0 = 0;
93             int i0 = check_point(p, cr, ci);
94             for (x = 1 ; x < w.width ; x++) {
95                 cr = p.Rmin + x * p.Rscale;
96                 int i = check_point(p, cr, ci);
97                 if (i != i0) {
98                     set_color(w, p, i0);
99                     w.drawLine(x0, y, x - 1, y);
100                     i0 = i;
101                     x0 = x;
102                 }
103             }
104             set_color(w, p, i0);
105             w.drawLine(x0, y, w.width - 1, y);
106         }
107     }
108
109     // Fonction de dessin principale, calcule la zone d'intérêt, appelle
110     // do_mandel(), pour dessiner l'ensemble, et permet le zoom.
111     static void mandel(DrawingWindow w)
112     {
113         Parameters p = initial_parameters;
114         while (true) {
115             p.Rscale = (p.Rmax - p.Rmin) / (w.width - 1);
116             p.Iscale = (p.Imax - p.Imin) / (w.height - 1);
117             do_mandel(w, p);
118             w.setColor("white");
119             w.drawText(5, 15, "Cliquer sur l'image pour zoomer");
120             w.waitMousePress();
121             int x = w.getMouseX();
122             int y = w.getMouseY();
123             // calcul des coordonnées du point cliqué
124             double Tr = p.Rmin + x * p.Rscale;
125             double Ti = p.Imax - y * p.Rscale;
126             // calcul de la nouvelle zone d'intérêt :
127             // zoom ×2 en direction du point cliqué
128             final int zoom = 2;
129             double Rmin2 = p.Rmin / zoom;
130             double Rmax2 = p.Rmax / zoom;
131             double Imin2 = p.Imin / zoom;
132             double Imax2 = p.Imax / zoom;
133             double Rshift = Tr - (Rmin2 + Rmax2) / 2;
134             double Ishift = Ti - (Imin2 + Imax2) / 2;
135             Rmin2 += Rshift;
136             Rmax2 += Rshift;
137             Imin2 += Ishift;
138             Imax2 += Ishift;
139             // affichage d'un rectangle autour de la nouvelle zone d'intérêt
140             w.setColor("white");
141             w.drawRect((int)Math.round((Rmin2 - p.Rmin) / p.Rscale),
142                        (int)Math.round((p.Imax - Imin2) / p.Iscale),
143                        (int)Math.round((Rmax2 - p.Rmin) / p.Rscale),
144                        (int)Math.round((p.Imax - Imax2) / p.Iscale));
145             p.Rmin = Rmin2;
146             p.Rmax = Rmax2;
147             p.Imin = Imin2;
148             p.Imax = Imax2;
149         }
150     }
151
152     public static void main(String[] args) {
153         DrawingWindow w = new DrawingWindow("Mandelbrot' set", 800, 800);
154         mandel(w);
155     }
156 }