|
|
Dernière mise à jour : 4 Mars 2012
PANOMAND est un programme Windows permettant d'explorer les ensembles de Mandelbrot et de Julia. Ces figures fractales sont créées par itération d'une fonction complexe z → f(z) + c, où c est une constante complexe. La présente version est limitée à la fonction puissance f(z) = zp, où p est un exposant entier ou réel supérieur à 1. Ce programme est distribué dans l'archive panomand.zip.
L'ensemble de Mandelbrot classique, nommé d'après le mathématicien Benoît Mandelbrot, correspond au cas p = 2. Plus précisément, il est défini comme l'ensemble des nombres complexes c pour lesquels la suite :
z0 = c
zn = (zn-1)2 + c
converge vers une valeur finie.
En pratique, la suite est évaluée en chaque point c du plan. Les points de l'ensemble sont colorés de la même couleur, et les points extérieurs à l'ensemble reçoivent une couleur fonction de leur vitesse de divergence.
Une vue générale de l'ensemble de Mandelbrot est donnée ici :
|
L'image est centrée en (-0,75, 0). L'échelle va de -2,35 à 0,85 horizontalement, et de -1,2 à 1,2 verticalement.
L'ensemble de Mandelbrot est en blanc. Il comporte plusieurs parties :
une cardioïde constituant la partie principale de l'ensemble (courbe en forme de coeur, à droite). Le "creux" de la cardioïde se situe au point (0,25, 0)
un disque principal de rayon 0,25 centré en (-1, 0) et tangent à la cardioïde au point (-0,75, 0)
un prolongement rectiligne (partie gauche de l'ensemble), montrant un mini-ensemble de Mandelbrot à l'abscisse -1,75
L'ensemble est hérissé de "bourgeons" de taille variable émettant des filaments. Les plus gros de ces bourgeons se trouvent aux deux pôles de la cardioïde. Chaque bourgeon est lui-même recouvert d'autres bourgeons, tandis que les filaments donnent naissance à de petites copies plus ou moins déformées de l'ensemble. Toutes ces structures se répètent à l'infini.
Les mathématiciens ont montré que :
l'ensemble de Mandelbrot est entièrement inclus dans le cercle de rayon 2 : les nombres complexes de module supérieur à 2 ne font donc pas partie de l'ensemble.
l'ensemble est connecté, c'est à dire d'un seul tenant : toutes ses parties sont reliées par des filaments, ceux-ci pouvant être infiniments fins, donc invisibles sur les images.
Le voisinage immédiat de l'ensemble est représenté en couleurs sombres, selon la méthode de l'estimateur de distance que nous étudierons plus loin.
L'extérieur de l'ensemble est constitué par les points pour lesquels la suite tend vers l'infini. Il est divisé en bandes de couleurs, selon le nombre d'itérations que la suite demande pour atteindre une valeur donnée appelée rayon d'échappement. Plus on se rapproche de l'ensemble, plus le nombre d'itérations augmente, et plus il augmente rapidement, de sorte que les bandes deviennent de plus en plus étroites.
Ces ensembles, nommés d'après le mathématicien Gaston Julia, sont définis d'une manière analogue à l'ensemble de Mandelbrot, sauf qu'ici le paramètre c est constant et la suite est initialisée avec les coordonnées zpixel du point considéré :
z0 = zpixel
zn = (zn-1)2 + c
Il y a donc un ensemble de Julia pour chaque valeur du paramètre c.
On montre que :
Lorsque le point c appartient à l'ensemble de Mandelbrot, l'ensemble de Julia est connecté, c'est-à-dire d'un seul tenant.
Dans le cas contraire, l'ensemble de Julia est formé d'une infinité de parties semblables.
|
c = (-0,75 ; 0)
Ce point appartient à l'ensemble
de Mandelbrot. |
c = (-0,75 ; 0,1) Ce point est en-dehors de l'ensemble de Mandelbrot. L'ensemble de Julia est discontinu. |
|
|
Pour les valeurs entières de p (> 2) l'ensemble de Mandelbrot est centré en (0,0) et comporte (p - 1) lobes symétriques. Quand p est impair, l'un de ces lobes est situé sur l'axe des x négatifs. Ce lobe est absent quand p est pair.
|
p = 3 2 lobes (symétrie d'ordre 2). Pas de lobe sur l'axe des x. |
p = 4 3 lobes (symétrie d'ordre 3). Un lobe sur l'axe des x. |
|
|
Les ensembles de Julia correspondants ont une symétrie d'ordre p.
Exemple avec p = 5 et c = (-0,5 ; 0,64) :
|
Les figures présentent des discontinuités. En effet pour les valeurs non entières de p, zp est évalué comme exp(p ln z). Or le logarithme d'un nombre complexe est une fonction à valeurs multiples. Les discontinuités s'expliquent par la nécessité de choisir une valeur unique en chaque point de l'image.
Exemple avec p = 3,5 :
|
Il est intéressant d'étudier la transition d'un entier impair p vers un entier pair, en passant par les valeurs intermédiaires. Cela se traduit par la formation progressive du lobe situé sur l'axe des x. Ce lobe se forme par fusion de multiples "bourgeons" qui se développent progressivement en s'entourant de motifs complexes.
|
p = 3,85 Une étape de la formation du lobe situé sur l'axe des x, à partir de plusieurs fragments. |
p = 3,85 Agrandissement (× 10) de l'image ci-contre, montrant quelques fragments et les motifs qui les entourent. |
|
|
Nous verrons ici quelques bases mathématiques du calcul de l'ensemble de Mandelbrot. Une connaissance élémentaire des nombres complexes est requise. Toutefois, on peut passer ce chapitre si l'on ne s'intéresse qu'aux images.
La suite zn = (zn-1)p + c est évaluée jusqu'à ce que le module |zn| soit supérieur au rayon d'échappement, ou que le nombre d'itérations soit supérieur à une valeur fixée à l'avance. Dans ce dernier cas, le point est considéré comme appartenant à l'ensemble.
Comme son nom l'indique, ce paramètre estime la distance entre le point testé et l'ensemble. Pour le calculer, on utilise le fait que le nombre d'itérations requis pour atteindre le rayon d'échappement augmente de plus en plus vite lorsqu'on s'approche de l'ensemble. Cette vitesse est estimée par la dérivée de la fonction itérée.
Pour l'ensemble de Mandelbrot, la fonction dépend du paramètre c. Il faut donc dériver par rapport à ce paramètre, ce qui donne :
z'n = p (zn-1)p-1 (z'n-1) + 1
avec z'0 = 0
Pour l'ensemble de Julia, le paramètre c est constant. La dérivée se réduit à :
z'n = p (zn-1)p-1 (z'n-1)
avec z'0 = 1
D = ( p |zn| ln |zn| ) / |z'n|
Cette valeur est d'autant plus faible que l'on est proche de l'ensemble.
Dwell = Iter - logp ( ln |zn| ) + logp ( ln Esc )
où Iter désigne le nombre d'itération et Esc le rayon d'échappement. La fonction logp est le logarithme de base p, tel que logp z = ln z / ln p
Les calculs précédents sont implantés dans la DLL fbmandel.bas écrite en FreeBASIC et basée sur la bibliothèque fbcomplex de calcul des nombres complexes. Nous présentons ici les principaux algorithmes utilisés ainsi que les fonctions exportées par la DLL.
L'image est en 640 × 480, 32 bits. Elle est centrée en (x0 , y0). La résolution est définie par le paramètre ZoomFact, tel que la valeur ZoomFact = 1 corresponde à une échelle verticale de 4 (soit une échelle horizontale de 4 × 4 / 3 = 5,333 ...). L'échelle verticale pour une valeur quelconque de ZoomFact est donc 4 / ZoomFact. Si Scale désigne l'échelle en pixels, on en déduit un facteur d'échelle :
ScaleFact = 4 / (Scale * ZoomFact)
Ce facteur représente la distance entre 2 pixels. Il permet de passer des coordonnées (Nx, Ny) d'un point, exprimées en pixels, à ses coordonnées algébriques (x, y) par :
x = x0 + ScaleFact * (Nx - HalfPicWidth) y = y0 - ScaleFact * (Ny - HalfPicHeight)
où HalfPicWidth et HalfPicHeight désignent la demi-largeur et la demi-hauteur de l'image (soit 320 et 240 dans notre cas).
Le balayage complet de l'image est alors assuré par les deux boucles suivantes :
for Ny = 0 to PicHeight - 1
yt = y0 - ScaleFact * (Ny - HalfPicHeight)
for Nx = 0 to PicWidth - 1
xt = x0 + ScaleFact * (Nx - HalfPicWidth)
pset (Nx, Ny), Mandelbrot(xt, yt)
next Nx
next Ny
où PicWidth et PicHeight désignent la largeur et la hauteur de l'image (soit 640 et 480 dans notre cas). La fonction Mandelbrot retourne la couleur du point.
Les itérations au point de coordonnées algébriques (xt, yt) se font dans la fonction Mandelbrot et portent simultanément sur la fonction complexe et sa dérivée, au moyen du code suivant :
if Julia then
c = cJulia
z = Cmplx(xt, yt)
dz = C_one
else
c = Cmplx(xt, yt)
z = C_zero
dz = C_zero
end if
Iter = 0
Module = CAbs(z)
do while Iter < MaxIter and Module < Esc
zp1 = z ^ p1
zn = z * zp1 + c
dzn = p * zp1 * dz
if not Julia then dzn = dzn + 1
Module = CAbs(zn)
z = zn
dz = dzn
Iter = Iter + 1
loop
où
On sort de la boucle de deux manières :
Si le nombre d'itérations atteint le maximum
autorisé (MaxIter), le point est considéré
comme faisant partie de l'ensemble, et on lui affecte la
couleur blanche :
if Iter = MaxIter then return &HFFFFFF
Cette méthode ne garantit pas que la suite converge puisqu'en
toute rigueur il faudrait faire un nombre infini d'itérations !
On risque donc d'inclure des points situés
très près de la frontière. Cela se traduit par
un aspect flou sur le graphique. Dans ce cas, il convient d'augmenter
la valeur de MaxIter, au détriment du temps de calcul.
Si le module du nombre complexe atteint la valeur du rayon
d'échappement, la suite diverge et le point ne fait pas partie
de l'ensemble. On calcule alors l'estimateur de distance et le
continuous dwell :
LnMod = log(Module)
Dist = p * Module * LnMod / CAbs(dzn)
Dwell = Iter - log(LnMod) / Lnp + LLE
où Lnp désigne le logarithme népérien de p et LLE = logp ( ln Esc )
La valeur du rayon d'échappement Esc a été fixée à 1010. C'est le calcul de l'estimateur de distance qui exige une valeur aussi élevée.
Nous utilisons une version simplifiée d'un algorithme décrit par Robert Munafo, et dont nous ne donnerons ici que les grandes lignes :
Les couleurs sont définies dans l'espace HSV (Hue, Saturation, Value)
La luminosité (Value) est attribuée en fonction de l'estimateur de distance, de sorte que les points proches de l'ensemble apparaissent en couleurs sombres. Cela facilite la détection des parties les plus ténues de l'ensemble, qui peuvent ne pas apparaître en tant que telles.
La teinte (Hue) et la saturation sont attribuées en fonction du continuous dwell.
Pour une meilleure apparence des bandes de couleurs, on peut dessiner une bande sur deux dans une teinte plus sombre.
La DLL exporte 4 fonctions:
Cette fonction initialise la valeur de p ainsi que les coordonnées c_X et c_Y du paramètre c pour l'ensemble de Julia. Si ces coordonnées sont toutes les deux nulles, l'ensemble de Mandelbrot sera tracé.
Exemple d'appel en PANORAMIC :
|
La fonction retourne 0 si p > 1, -1 sinon.
Cette fonction définit les caractéristiques du graphique au moyen des paramètres suivants :
Remarques :
La luminosité est contrôlée par le paramètre DistFact et augmente lorsque ce paramètre augmente.
La densité des couleurs est contrôlée par le paramètre ColorFact : plus ce paramètre est élevé (en valeur absolue) plus il y aura de couleurs sur l'image. Pour une image en noir et blanc, fixez ColorFact à zéro.
Si ColorFact est positif, l'alternance des bandes de couleurs entourant l'ensemble est accentuée en assombrissant une bande sur deux. Cet effet peut être supprimé en donnant à ColorFact une valeur négative, auquel cas la coloration prendra plutôt l'aspect d'un gradient continu.
Exemple d'appel en PANORAMIC :
|
Cette fonction dessine le graphique. Elle ne prend pas de paramètres et retourne toujours 0. Elle doit être appelée après les deux fonctions précédentes.
Exemple d'appel en PANORAMIC :
|
Cette fonction permet d'obtenir les coordonnées algébriques (x, y) d'un point, connaissant ses coordonnées (Nx, Ny) en pixels, ainsi que les coordonnées algébriques (x0, y0) du centre de l'image.
Exemple d'appel en PANORAMIC :
|
Pour utiliser cette fonction, il faut avoir appelé auparavant SetGraphParams, faute de quoi le facteur d'échelle ne serait pas initialisé.
Ce programme écrit en PANORAMIC fournit une interface graphique à la DLL précédente.
![]() |
Les valeurs des différents paramètres sont saisis dans les cases correspondantes. Les coordonnées X et Y sont celles du centre de l'image. Le bouton "Graph" lance le calcul. L'image est générée dans une fenêtre secondaire, puis transférée dans la fenêtre principale. L'image est sauvegardée dans le fichier fractal.bmp. Les paramètres sont enregistrés dans le fichier texte fractal.par. Le bouton "Save file" permet de sauvegarder sous un autre nom, tandis que le bouton "Open file" permet de charger une image déjà créée.
Pour passer de l'ensemble de Mandelbrot à l'ensemble de Julia, cliquez sur le bouton "Mandelbrot". Il prendra le titre "Julia" et les coordonnées du centre de l'image deviendront celles du paramètre c pour l'ensemble de Julia, apparaissant dans les cases "c_X" et "c_Y". Les anciennes coordonnées seront remplacées par zéro, de manière à centrer l'ensemble en (0, 0).
En cliquant sur un point de l'image, on obtient ses coordonnées dans les cases X et Y. On peut ainsi faire des agrandissements en augmentant progressivement le facteur de zoom.
Nous présentons ici quelques images réalisées avec PANOMAND et montrant l'une des parties les plus célèbres de l'ensemble classique de Mandelbrot : la vallée des hippocampes.
Cette région, également appelée seahorse valley, se trouve entre la cardioïde et le disque principal. Son versant "est" contient des structures en forme d'hippocampe, tandis que son versant "ouest" contient des structures en forme de double spirale.
|
Fig. 01 Vue générale de la vallée des hippocampes |
|
|
Fig. 02a
Agrandissement du versant "ouest" de la vallée, |
Fig. 02b Agrandissement du versant "est" de la vallée, montrant un motif en hippocampe. |
|
|
|
Fig. 03
Partie supérieure de la "queue" de l'hippocampe, |
Fig. 03a
Agrandissement d'une "double crosse". |
|
|
|
Fig. 04 Agrandissement du mini-ensemble de la figure précédente. |
Fig. 05 Plongée dans la "vallée des hippocampes" de ce mini-ensemble. |
|
|
|
Fig. 06 A l'intérieur de cette vallée, on retrouve les motifs en "double crosse" ... |
Fig. 07
... mais au lieu d'un mini-ensemble de Mandelbrot, on y trouve une
structure |
|
|
|
Fig. 08 Agrandissement de l'EJS. Noter la symétrie d'ordre 2. |
Fig. 09 Agrandissement du centre de l'EJS. Le motif central est appelé "noyau". |
|
|
|
Fig. 10 Agrandissement du noyau, avec au centre : le "nucléole" ... |
Fig. 11 ... qui contient un mini-ensemble de Mandelbrot. |
|
|
L'agrandissement de la dernière image atteint pratiquement la limite de ce que l'on peut faire avec PANOMAND. Nous sommes donc obligés d'arrêter notre exploration ici. Heureusement, il y a beaucoup d'autres régions intéressantes dans l'ensemble de Mandelbrot, en particulier :
La "pointe" de l'ensemble contient une infinité de mini-ensembles dont le principal est visible sur la vue générale à l'abscisse -1,75. Les vallées de ces ensembles contiennent de nombreux EJS.
La vallée des sceptres (entre le disque principal et son "bourgeon" ouest).
La vallée des éléphants correspond au creux de la cardioïde.
Nous espérons que ces quelques exemples vous auront donné l'envie d'explorer plus avant l'ensemble de Mandelbrot.
N'hésitez pas à générer vos propres images. Il y a encore beaucoup de choses à découvrir !
Mandelbrot Dazibao. Excellent site avec des tutoriels et des programmes en QBasic. PANOMAND est basé sur l'un d'entre eux.
Mu-Ency. Encyclopedia of Mandelbrot set, par Robert Munafo. Décrit notamment la méthode de coloration utilisée dans PANOMAND.
High Precision Deep Zoom. Images de l'ensemble à très forts grandissements.
Précédent : Une calculatrice en PANORAMIC et FreeBASIC
|
|