Une pensée pour Benoît Mandelbrot
Benoît Mandelbrot, l'inventeur des objets fractals, est décédé le 14 octobre 2010.
Quelques lignes de JavaScript en son honneur:
(function(canevas) {
if (canevas.getContext) {
var largeur = parseInt(canevas.width, 10); // px
var hauteur = parseInt(canevas.height, 10); // px
var definition = largeur > hauteur ?
0.4*hauteur: 0.4*largeur; // px/unité
var origine_x = largeur / 1.3;
var origine_y = hauteur / 2;
var contexte = canevas.getContext("2d");
var image_data = contexte.getImageData(0, 0, largeur, hauteur);
var pixels = image_data.data;
var pixel = 0; // Le numéro du pixel courant.
var index = 0; // L'index courant dans le tableau «pixels».
// Incrémenté de 4 à chaque itération.
// Pour éviter de bloquer l'interface, le
// calcul est découpé en tranches de 50 ms.
setTimeout(function() {
var start_time = +new Date();
do {
var max_iter = 100;
do {
// Déterminer la position du pixel dans le plan
// des complexes à partir de son index.
var x = (pixel % largeur - origine_x) / definition;
var y = (pixel / largeur - origine_y) / definition;
// Évaluer la convergence pour ce point.
var mu = mandelbrot(x, y, 40, 3);
// Coloration volontairement simpliste. À ajuster
// selon les besoins.
var red = mu * 12;
var green = mu * 12;
var blue = mu * 55;
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
pixels[index ] = red;
pixels[index+1] = green;
pixels[index+2] = blue;
pixels[index+3] = 255;
index += 4;
pixel++;
max_iter--;
} while (index < pixels.length &&
max_iter != 0)
} while (index < pixels.length &&
(+new Date() - start_time < 50));
if (index < pixels.length) {
setTimeout(arguments.callee, 25);
} else {
contexte.putImageData(image_data, 0, 0);
}
}, 25);
}
// Les composantes d'un nombre complexe, a et b.
// Retourne le niveau de convergence normalisé.
function mandelbrot(a, b, max_iter, escape_radius) {
var x = y = 0;
var x_n1 = y_n1 = 0;
var iter_count = 0;
var max_iter = max_iter || 18;
var escape_radius = escape_radius || 3;
while (Math.sqrt(x*x+y*y) < escape_radius &&
iter_count < max_iter) {
x_n1 = x*x - y*y + a;
y_n1 = 2*x*y + b;
x = x_n1;
y = y_n1;
iter_count++;
}
// Normaliser avant de retourner le niveau de convergence.
return iter_count - (Math.log(Math.log(Math.sqrt(x*x+y*y)))) / Math.log(2.0);
}
})(document.getElementById("surface"));
Ce qui donne l'ensemble de Mandelbrot[1]:
Pour un tour d'horizon complet sur la coloration des fractales, voir la thèse de Jussi Härkönen: On Smooth Fractal Coloring Techniques.