====== Ensemble de Mandelbrot ====== Je donne ici une solution processing au TD [[nsi:tds:maths:fractales:mandelbrot_set|Mandelbrot]]. // Mandelbrot final int ITERATIONS = 500; // zoom quand on clic à l'écran final double ZOOM = 1.5; // colormap définie à la main color[] colors = { color(100, 14, 0), color(100, 70, 0), color(94, 100, 0), color(60, 120, 10), color(0, 100, 30), color(0, 100, 80), color(20, 80, 80), color(30, 0, 80), color(80, 0, 80), color(50, 0, 50), color(20, 0, 20), color(0, 0, 0) }; Mandelbrot M = new Mandelbrot(-.5, 0, .01); void setup(){ size(1000, 800); fill(255); M.display(); } void draw(){ } class Mandelbrot { double centerx, centery, dot; Mandelbrot(double cx, double cy, double pixel_size){ /* initialise un panneau centré sur cx, cy avec un pixel de taille pixel_size */ centerx = cx; centery = cy; dot = pixel_size; } void zoom(int col, int line){ /* zoom en laissant inchangé le pixel en lig et col */ double x = centerx + (col - width/2)*dot; double y = centery - (line - height/2)*dot; dot = dot/ZOOM; centerx = x - (col - width/2)*dot; centery = y + (line - height/2)*dot; display(); } void display() { /* calcule et trace l'ensemble de Mandelbrot */ loadPixels(); for (int line=0; line= 4) { return 1 - max(0, i - log(m2)/log(4))/ITERATIONS; } } return 0; } color getColor(float rscore{ /* score: facteur entre 0 et 1. renvoie la couleur correspondante dans la table colors */ int n = colors.length; if (score == 1){ return colors[n-1]; } float v = score*(n-1); int i = floor(v); float f = v - i; return lerpColor(colors[i], colors[i+1], f); } } void mouseClicked() { M.zoom(mouseX, mouseY); } === lissage entre les couleurs === La colormap est assez limitée. On veut passer linéairement d'une couleur à l'autre par un dégradé. Par exemple ici, il y a 12 images dans la colormap, ''colors[0]'' à ''colors[11]''. pour un score de 0, on veut ''colors[0]''. Pour un score de 1 on veut ''colors[11]''. Donc en gros, on veut la couleur d'indice ''11*score''. Et si ''score = 0.4'' ? Alors on voudrait ''colors[4.4]'' ? Eh bien on va prendre qui se situe à 40 % du dégradé allant de ''colors[4]'' jusqu'à ''colors[5]''. La fonction ''lerpColor'' sert justement à calculer cette couleur intermédiaire. === meilleur lissage du score === Quand on calcule le score, on obtient toujours un résultat qui est en ''i/ITERATIONS''. Donc on peut avoir des variations brusque selon que d'un point à un autre, on passe de ''i'' à ''i+1''. Mais quand un point sort du cercle de rayon 2, c'est à dire quand $|z_n|\geq 2$, , il peut sortir plus ou moins fort. On fait donc le calcul $\frac{\ln(|z_n|)}{\ln(2)}$, ou plutôt $\frac{\ln(|z_n|^2)}{\ln(4)}$, pour ajuster un peu le score. C'est un calcul empirique, cela donne un bon résultat. C'est une simple astuce pour obtenir un résultat plus joli, mais cela n'a pas grand sens mathématique.