Sunteți pe pagina 1din 20

Dessiner la fractale de Mandelbrot

Par berdes1

www.siteduzero.com

Licence Creative Commons BY-NC-SA 2.0 Dernire mise jour le 3/12/2011

Sommaire

1/19

Sommaire
Sommaire ........................................................................................................................................... 1 Lire aussi ............................................................................................................................................ 0 Dessiner la fractale de Mandelbrot .................................................................................................... 2
L'ensemble de Mandelbrot ................................................................................................................................................ 2
Ses caractristiques .................................................................................................................................................................................................... 2 La formule ................................................................................................................................................................................................................... 3

Prliminaires ...................................................................................................................................................................... 3
Les nombres complexes ............................................................................................................................................................................................. 3 Les suites .................................................................................................................................................................................................................... 4

L'algorithme ....................................................................................................................................................................... 4 En couleur, c'est plus joli ................................................................................................................................................... 8 Faire des zooms sur l'image ........................................................................................................................................... 14
Le zoom .................................................................................................................................................................................................................... 14 Les coordonns du plan complexe ........................................................................................................................................................................... 14 Le nombre d'itration maximum ................................................................................................................................................................................ 14

Pour aller plus loin ........................................................................................................................................................... 15


Les ensembles de Julia ............................................................................................................................................................................................. 15 Buddhabrot ................................................................................................................................................................................................................ 16 Mandelblub ................................................................................................................................................................................................................ 18 Partager ..................................................................................................................................................................................................................... 19

www.siteduzero.com

Dessiner la fractale de Mandelbrot

2/19

Dessiner la fractale de Mandelbrot

Par

berdes1

Mise jour : 01/11/2010 Difficult : Intermdiaire

Dure d'tude : 4 heures

244 visites depuis 7 jours, class 365/778 Ce tutoriel aura pour but de vous faire dcouvrir l'univers des fractales en informatique et plus particulirement celui de l'ensemble de Mandelbrot. Attention, ce tutoriel requiert une certaine base de connaissance en mathmatiques. Mme si je vais expliquer le plus dur, je pense qu'un niveau seconde est requis.

Tout d'abord, qu'est-ce qu'une fractale (ou figure fractale)? Je ne vais pas vous donner la vrai dfinition qui est tout fait incomprhensible pour la plupart des personnes. En fait, une fractale est une figure complexe qui possde une infinit de dtails, quel que soit l'chelle laquelle on la regarde. De plus on retrouve souvent le mme motif ou un motif similaire dans le motif de la fractale en lui-mme. Pour finir, il faut dire qu'une fractale est trop irrgulire pour que l'on puisse la dcrire par des termes gomtriques habituels. V quelques exemples de fractales : oici

V ous avez sans doute dj vu la dernire. C'est l'ensemble de Mandelbrot, la fractale sur laquelle nous allons travailler. Sommaire du tutoriel :

L'ensemble de Mandelbrot Prliminaires L'algorithme En couleur, c'est plus joli Faire des zooms sur l'image Pour aller plus loin

L'ensemble de Mandelbrot Ses caractristiques


L'exemple de l'ensemble de Mandelbrot donn dans l'introduction peut tre trompeur, car il y a plein de couleurs, mais en ralit la fractale n'est qu'une figure. Sur l'image ci-dessous, on voit clairement la fractale en noir.

www.siteduzero.com

Dessiner la fractale de Mandelbrot

3/19

La grosse forme qui ressemble presque un cercle est appele cardiode (vous avez une petite explication sur Wikipdia). Comme vous pouvez le voir, le mme cercle gauche de la cardiode est lui-mme entour de cercles de diffrentes tailles se rpte tout au long de la fractale et ce, de manire infinie. Une autre caractristique, c'est les petits points qui sont gauches de la fractale. Normalement, ils forment un segment qui s'arrte brusquement (vous pouvez le voir sur la fractale en couleur). Et bien, si on zoom sur ce segment on retrouvera toujours la fractale et ce quel que soit le zoom que l'on prend.

La formule
En se servant des connaissances que vous avez acquises juste avant, vous pouvez enfin comprendre la formule qui dfinit l'ensemble de Mandelbrot. Citation : wikipedia L'ensemble de Mandelbrot est une fractale qui est dfinie comme l'ensemble des points suite rcurrente dfinie par : et la condition ne tend pas vers l'infini (en module). Pour faire plus simple, on regarde chaque point du plan complexe (de l'image) et on regarde si la suite tend vers l'infini en module ( = si le module de pour trs grand se rapproche de l'infini). En ralit, ce genre de calcul est bien compliqu pour notre pauvre ordinateur et donc, nous avons seulement besoin de tester si le module de dpasse 2 un moment. S'il ne le dpasse pas, c'est qu'il fait partie de la fractale. Mais comment savoir s'il ne le dpasse pas? du plan complexe pour lesquels la

On va tout simplement regarder si il le dpasse jusqu' un certain rang assez grand pour que l'on puisse raisonnablement penser qu'il ne le dpassera pas ensuite. C'est le rang (appel nombre d'itration) que l'on va choisir qui va fixer en partie la qualit du rendu final. Si le nombre d'itration n'est pas assez grand, il va considrer trop de points comme faisant partie de la fractale, alors que si le nombre d'itration est trop grand, la fractale aura tendance tre trop nette (c'est un peu le problme de la fractal en noir et blanc que je vous ai montr juste au-dessus).

Prliminaires Les nombres complexes


Afin de comprendre la formule qui dfinit l'ensemble de Mandelbrot, il faut tout d'abord savoir ce qu'est un nombre complexe. Un nombre complexe est un nombre qui possde deux parties : une partie relle et une partie imaginaire. La partie rel est un nombre quelconque appartenant l'ensemble des rels. La partie imaginaire est aussi un nombre appartenant l'ensemble des rels. C'est quoi cette arnaque? Pourquoi on a un nombre compos de deux nombres?

Et bien, le nombre complexe aura pour valeur sa partie rel additionn sa partie imaginaire, elle-mme multiplie par i. Si on note

www.siteduzero.com

Dessiner la fractale de Mandelbrot

4/19

x la partie rel et y la partie imaginaire, le nombre complexe, not z, sera . Notez au passage lutilisation de x et y, habituellement rserve pour les coordonns d'un point. La plus grosse difficult des nombre complexe vient du fait que la seule dfinition de l'on peut donner de i est que . Mais, je croyais qu'un nombre au carr tait toujours positif ?

C'est vrai pour tous les rels (les nombre que l'on tudie le plus souvent), mais ce n'est pas forcment vrai pour les nombres complexes, cause de la dfinition mme de i. Il faudra vous y faire. Un exemple de nombre complexe : . 3 est la partie rel et 5 la partie imaginaire. i est coll au 5 tout simplement car c'est une multiplication. V quelques exemples doprations sur les nombres complexes pour que vous compreniez: oici Laddition : . Comme vous pouvez le voir, il suffit d'additionner les parties rels et les parties imaginaires entre elles pour obtenir le rsultat. La multiplication : . D'abord, on dveloppe : . Ensuite, on rassemble les lments ensemble et on simplifie : . Et l, miracle : , donc on peut continuer simplifier : . Les nombres complexes peuvent tre utiliss pour reprsenter un point dans un repre. Par exemple, le point de coordonn peut tre reprsent par le nombre complexe . On vois que la partie rel du nombre complexe correspond l'abscisse du point et la partie imaginaire l'ordonne. Dans la cas gnral, le nombre complexe correspond au point M de coordonnes . On dit que z est l'affixe de M. En continuant l-dessus, il faut savoir que la distance OM correspond au module du nombre z. On peut donc en dduire que le module de z, not , est gal . Retenez bien cette notion, c'est important pour la suite. C'tait la partie la plus dur, donc si vous avez compris tout a, le reste devrait rester assez simple.

Les suites
Le second point de math qu'il faut connaitre est les suites. Citation : Wikipdia En mathmatiques, une suite est une famille d'lments indexe par les entiers naturels. La dfinition de Wikipdia est plus ou moins claire, mais le plus important est la partie en gras. Par exemple, si on parle de la suite , le nom de la suite est et l'index est . Une suite peut tre dfinie en fonction de . C'est le cas le plus simple, en voici un exemple : . C'est un peu comme une fonction, sauf que est forcment un entier positif : . Mais, il existe une autre mthode pour dfinir une suite : on dfinit le premier terme de la suite et une formule de rcurrence qui va nous permettre de calculer un terme en fonction du prcdent. Un exemple : le premier terme et la formule de rcurrence . Pour calculer , on va procder comme ceci :

Rien de bien compliqu au final si on a dj compris le principe des fonctions. Si vous tes arrivs ici vivants et que vous avez compris l'essentiel, la suite de ce tutoriel devrais vous sembler trs simple.

L'algorithme
Bon, maintenant que vous savez comment dfinir la fractale de Mandelbrot, on va passer la pratique : on va crer l'algorithme qui va nous permettre de dessiner la fractale. Pourquoi un algorithme plutt qu'un code? Tout simplement car on peut dessiner l'ensemble de Mandelbrot avec quasiment tous les langages, donc pour que tout le monde puisse le traduire, on va dfinir une

www.siteduzero.com

Dessiner la fractale de Mandelbrot

5/19

mthode qui doit marcher quel que soit le langage que l'on utilise. Ce sera ensuite vous de le traduire dans votre langage favori. Le premier jet est assez simple : Code : Autre - Algorithme dfinir iteration_max = 50 Pour chaque dfinir dfinir dfinir point de coordonnes (x; y) du plan : c = x + iy z = 0 i = 0

Faire z = z*z + c i = i+1 Tant que module de z < 2 et i < iteration_max si i = iteration_max dessiner le pixel correspondant au point de coordonn (x; y) finSi finPour

Notez que le i dans ce code correspond au nombre d'itration et non pas l'unit imaginaire i.

Comme vous pouvez le voir, ce code est trs simple, mais sera difficilement traduisible si on utilise un langage qui ne comprend pas les nombres complexes. C'est pour cela que l'on va dfinir 2 variables pour le nombre z : une pour la partie relle ( ) et une pour la partie imaginaire ( ). On va faire de mme pour c. Le calcul z = z*z + c devient donc :

Il ne reste plus qu' sparer la partie entire et la partie imaginaire :

Attention, il ne s'agit pas d'galits mathmatique, mais de la dcomposition du calcul de z dans le code.

De plus, au lieux de calculer le module de z et le comparer 2, on va juste calculer le carr de ses composantes (partie relle et partie imaginaire) et comparer le rsultat 4 car : On peut donc changer le code comme ceci : Code : Autre dfinir iteration_max = 50 Pour chaque dfinir dfinir dfinir dfinir dfinir point c_r = c_i = z_r = z_i = i = 0 de coordonnes (x; y) du plan : x; y; 0 0

Faire dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i

www.siteduzero.com

Dessiner la fractale de Mandelbrot


i = i+1 Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max si i = iteration_max dessiner le pixel correspondant au point de coordonn (x; y) finSi finPour

6/19

On stocke z_r dans une variable temporaire pour viter d'utiliser la nouvelle valeur de z_r dans le calcul de z_i. Rien ne vous choque? et bien a devrait. En informatique, on va utiliser une image pour dessiner la fractale, sauf que l on utilise un plan pour les coordonnes de x et y. Il va donc falloir faire correspondre ces deux grandeurs. Tout d'abord, il faut savoir que l'ensemble de Mandelbrot est toujours compris entre -2.1 et 0.6 sur l'axe des abscisse et entre -1.2 et 1.2 sur l'axe des ordonnes. Il y a deux techniques pour grer la diffrence de taille entre le plan et limage utilise. La plus simple consiste dfinir la zone que l'on va dessiner et une valeur de zoom. On calculera ensuite la taille de l'image partir de ces informations : Code : Autre // on dfinit la zone que l'on dessine. Ici, la fractale en entire dfinir x1 = -2.1 dfinir x2 = 0.6 dfinir y1 = -1.2 dfinir y2 = 1.2 dfinir zoom = 100 // pour une distance de 1 sur le plan, on a 100 pixel sur l'image dfinir iteration_max = 50 // on calcule la taille de l'image : dfinir image_x = (x2 - x1) * zoom dfinir image_y = (y2 - y1) * zoom Pour x = 0 tant que Pour y = 0 tant dfinir c_r dfinir c_i dfinir z_r dfinir z_i dfinir i = x < que = x = y = 0 = 0 0 image_x par pas de 1 y < image_y par pas de 1 / zoom + x1 / zoom + y1

Faire dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i i = i+1 Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max si i = iteration_max dessiner le pixel de coordonn (x; y) finSi finPour finPour

Avec ce code, on obtiendra une image de 270*240 pixels. Les avantages de cette technique : On dfinit soit-mme l'chelle (le zoom) que l'on veut La fractale toujours les mmes proportions

Linconvnient : on ne connait pas la taille finale de l'image sans la calculer sois-mme avant. Il y a donc des risques de se retrouver avec une image bien trop grande (et l'ordi va patauger pour dessiner la fractale) ou une image bien trop petite.

www.siteduzero.com

Dessiner la fractale de Mandelbrot

7/19

La deuxime technique est tout simplement de dfinir la zone que l'on veut dessiner et la taille de l'image. Le zoom sera calcul en fonction de ces valeurs : Code : Autre // on dfinit la zone que l'on dessine. Ici, la fractale en entire dfinir x1 = -2.1 dfinir x2 = 0.6 dfinir y1 = -1.2 dfinir y2 = 1.2 dfinir image_x = 270 dfinir image_y = 240 dfinir iteration_max = 50 // on calcule la taille de l'image : dfinir zoom_x = image_x/(x2 - x1) dfinir zoom_y = image_y/(y2 - y1) Pour x = 0 tant que Pour y = 0 tant dfinir c_r dfinir c_i dfinir z_r dfinir z_i dfinir i = x < que = x = y = 0 = 0 0 image_x par pas de 1 y < image_y par pas de 1 / zoom_x + x1 / zoom_y + y1

Faire dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i i = i+1 Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max si i = iteration_max dessiner le pixel de coordonn (x; y) finSi finPour finPour

L'avantage : on a une image de la taille que l'on veut, donc il n'y a pas de risque de se retrouver avec une image de 10000*10000. L'inconvnient : moins de calculer soit-mme la taille de l'image en fonction de la taille de la zone dessiner (et l, a reviendrait la premire technique), on se retrouve souvent avec une image compltement disproportionne. V pourquoi je prfre utiliser la premire technique, quitte avoir une validation qui demande si on veut vraiment dessiner la oil fractale en indiquant la taille de l'image. partir de ce stade, vous pouvez dj faire un rendu de la fractale. V ce que j'ai fait en recopiant le code : oici

www.siteduzero.com

Dessiner la fractale de Mandelbrot

8/19

Le chiffre en haut gauche, c'est le temps de gnration en secondes. C'est un peu long, mais en grosse partie cause de PHP qui n'est pas vraiment adapt. D'aprs mon exprience, en utilisant un langage bas niveau tel que C/C++, on peut arriver des rsultats 10 20 fois plus rapide. Dailleurs, en parlant du PHP, voici le code que j'ai utilis pour gnrer la fractale : Code : PHP <?php $x1 = -2.1; $x2 = 0.6; $y1 = -1.2; $y2 = 1.2; $zoom = 100; $iterations_max = 50; $image_x = ($x2 - $x1)*$zoom; $image_y = ($y2 - $y1)*$zoom; // on cr l'image et les couleurs, inutile ici de remplire l'image vu que on dessinera tous les pixels $image = imagecreatetruecolor($image_x, $image_y); $blanc = imagecolorallocate($image, 255, 255, 255); $noir = imagecolorallocate($image, 0, 0, 0); imagefill($image, 0 ,0 , $blanc); $debut = microtime(true); for($x = 0; $x < $image_x; $x++){ for($y = 0; $y < $image_y; $y++){ $c_r = $x/$zoom+$x1; $c_i = $y/$zoom+$y1; $z_r = 0; $z_i = 0; $i = 0; do{ $tmp = $z_r; $z_r = $z_r*$z_r - $z_i*$z_i + $c_r; $z_i = 2*$tmp*$z_i + $c_i; $i++; } while($z_r*$z_r + $z_i*$z_i < 4 AND $i < $iterations_max); if($i == $iterations_max) imagesetpixel($image, $x, $y, $noir);

$temps = round(microtime(true) - $debut, 3); imagestring($image, 3, 1, 1, $temps, $noir); header('Content-type: image/png'); imagepng($image);

En couleur, c'est plus joli


Nous y voil enfin, dans la partie qui vous permettra de faire de super beaux rendus qui feront craquer tout le monde (ou pas). L'intgration de la couleur dans la fractale se fait de manire trs simple : vous avez remarqu que quand on sort de la boucle qui teste si tend vers l'infini en module, on ne dessine rien? Et bien il suffit de dessiner le pixel avec une couleur en fonction du nombre d'itration que l'on a mis pour trouver que tend vers l'infini en module. On va prendre l'exemple simple de la fractale entoure de bleu. Donc plus on met d'itration, plus le bleu est clair. Code : Autre

www.siteduzero.com

Dessiner la fractale de Mandelbrot


dfinir dfinir dfinir dfinir dfinir dfinir

9/19

x1 = -2.1 x2 = 0.6 y1 = -1.2 y2 = 1.2 zoom = 100 // pour une distance de 1 sur le plan, on a 100 pixel sur l'image iteration_max = 50

dfinir image_x = (x2 - x1) * zoom dfinir image_y = (y2 - y1) * zoom Pour x = 0 tant que Pour y = 0 tant dfinir c_r dfinir c_i dfinir z_r dfinir z_i dfinir i = x < que = x = y = 0 = 0 0 image_x par pas de 1 y < image_y par pas de 1 / zoom + x1 / zoom + y1

Faire dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i i = i+1 Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max

si i = iteration_max dessiner en noir le pixel de coordonn (x; x) sinon dessiner avec couleur rgb(0, 0, i*255/iterations_max) le pixel de coordonn finSi finPour finPour

V le rendu (mmes paramtres que pour le prcdent) : oici

C'est loin d'tre trs beau, mais la base est l. Sachez que pour trouver les bons paramtres et les bonnes couleurs, il vous faudra beaucoup de tests souvent infructueux. Pensez tout de mme que souvent les plus belles fractales ont des dgrads de plusieurs couleurs. Ici, on ne va que du noir vers le bleu. Mais on peut trs bien aller du noir vers le bleu, puis vers le blanc. On peut mme faire un cycle de couleur : noir -> bleu -> blanc -> vert -> noir et on recommence. Si vous regardez bien pour le premier ensemble de mandelbrot que je vous ai montr (dans l'introduction), le crateur a utilis le dgrad bleu fonc -> blanc -> jaune -> violet -> bleu -> blanc. V ous n'tes pas non plus oblig d'utiliser un dgrad linaire, vous de laisser parler votre imagination. V le code PHP de la fractale en couleur : oici

www.siteduzero.com

Dessiner la fractale de Mandelbrot


Code : PHP <?php $x1 = -2.1; $x2 = 0.6; $y1 = -1.2; $y2 = 1.2; $zoom = 100; $iterations_max = 50; $image_x = ($x2 - $x1)*$zoom; $image_y = ($y2 - $y1)*$zoom; // on cr l'image et les couleurs, inutile ici de remplire l'image vu que on dessinera tous les pixels $image = imagecreatetruecolor($image_x, $image_y); $blanc = imagecolorallocate($image, 255, 255, 255); $noir = imagecolorallocate($image, 0, 0, 0); imagefill($image, 0 ,0 , $blanc); // on dfinit la liste des couleurs du dgrad ici, a vite de devoir faire appel imagecoloralocate chaque pixel $couleurs = array(); for($i = 0; $i < $iterations_max; $i++) $couleur[$i] = imagecolorallocate($image, 0, 0, $i*255/$iterations_max); $debut = microtime(true); for($x = 0; $x < $image_x; $x++){ for($y = 0; $y < $image_y; $y++){ $c_r = $x/$zoom+$x1; $c_i = $y/$zoom+$y1; $z_r = 0; $z_i = 0; $i = 0; do{ $tmp = $z_r; $z_r = $z_r*$z_r - $z_i*$z_i + $c_r; $z_i = 2*$tmp*$z_i + $c_i; $i++; } while($z_r*$z_r + $z_i*$z_i < 4 AND $i < $iterations_max); if($i == $iterations_max) imagesetpixel($image, $x, $y, $noir); else imagesetpixel($image, $x, $y, $couleur[$i]);

10/19

$temps = round(microtime(true) - $debut, 3); imagestring($image, 3, 1, 1, $temps, $blanc); header('Content-type: image/png'); imagepng($image);

Finalement, pour ceux qui ont besoin de plus de performances, voici le code en C++ avec SFML (merci Gigotdarnaud de m'avoir fourni le code) : Secret (cliquez pour afficher) Code : C++ #include <iostream> #include <SFML/Graphics.hpp>

www.siteduzero.com

Dessiner la fractale de Mandelbrot


sf::Mutex mutex; bool threadRun; class Render : public sf::Thread { // Cette classe threade va s'occuper des calculs, afin de ne pas bloquer l'affichage public: Render(sf::Image** _im, unsigned int _zoom, unsigned int _max_iteration, bool _inColor=false) { *_im=&im; //On utilise un pointeur de pointeur afin que le thread principal puisse afficher l'image inColor=_inColor; x1=-2.1; x2=0.6; y1=-1.2; y2=1.2; zoom=_zoom; iteration_max=_max_iteration; image_x = static_cast<unsigned int>((x2 - x1) * zoom); image_y = static_cast<unsigned int>((y2 - y1) * zoom); std::cout << "Image size : (" << image_x << ";" << image_y << ")" << std::endl; im=sf::Image(image_x, image_y, sf::Color::Black); //On cre une image vide (noire) threadRun=true; //Cette variable globale sert stopper le thread lorsque l'on ferme la fentre. } private: virtual void Run() //La fonction principale du thread de rendu { for(unsigned int x=0;x<image_x&&threadRun;x++) //On parcourt l'axe des X { for(unsigned int y=0;y<image_y&&threadRun;y++) //On parcourt l'axe des Y { double c_r=x/static_cast<double>(zoom)+x1; double c_i=y/static_cast<double>(zoom)+y1; double z_r=0; double z_i=0; double i=0; do {

11/19

double tmp=z_r; z_r=z_r*z_r-z_i*z_i+c_r; z_i=2*z_i*tmp+c_i; ++i;

while(z_r*z_r+z_i*z_i<4&&i<iteration_max&&threadRun); if(threadRun) { mutex.Lock(); //On verouille l'image, afin que les deux threads n'entrent pas en colision if(inColor) {

www.siteduzero.com

Dessiner la fractale de Mandelbrot


if(i!=iteration_max) { im.SetPixel(x, y, sf::Color(0, 0, static_cast<int>(i*255/iteration_max))); //On change la couleur du pixel } } else { if(i==iteration_max) im.SetPixel(x, y, sf::Color::White); } mutex.Unlock(); //Et on dvrouille } } } if(threadRun) { //Si l'on est arriv ici, c'est que l'on a calcul tout ce qui tait calculable. std::cout << "Render is over (" << elapsed.GetElapsedTime() << "s) ! Saving..."<<std::endl; im.SaveToFile("Fractal.png"); std::cout << "Saved in \"Fractal.png\""<<std::endl; } else { //Si on est l, c'est que le rendu a t stopp prmaturment par l'utilisateur. std::cout << "Rendering aborded."<<std::endl; } } double x1; double x2; double y1; double y2; unsigned int zoom; unsigned int iteration_max; unsigned int image_x; unsigned int image_y; sf::Clock elapsed; //Cet objet servira dterminer le temps de rendu postriori bool inColor; }; sf::Image im;

12/19

int main() { //On cre la fenetre, on prpare le sprite et l'image... const unsigned int RESO_X=800; const unsigned int RESO_Y=600; sf::RenderWindow App(sf::VideoMode(RESO_X, RESO_Y, 32), "Fractales"); App.SetFramerateLimit(60); sf::Image* ima=NULL; Render rend(&ima, 2500, 500, true); //On cr l'objet du rendu, en lui donnant les paramtres de la fractale (zoom, itrations max, et couleur) sf::Sprite spr; spr.SetImage(*ima); //Cet objet sert limiter l'appel aux fonctions d'affichage,

www.siteduzero.com

Dessiner la fractale de Mandelbrot


qui bloquent le thread de rendu cause des mutexs. sf::Clock clock; const float time = 0.25; //Cet objet sert dterminer le zoom de la vue, la position de la camra, etc. Elle n'a qu'une influence sur la fentre, la fractale est toujours la mme sf::View view(sf::Vector2f(ima->GetWidth()/2,ima>GetHeight()/2), sf::Vector2f(RESO_X/2,RESO_Y/2)); App.SetView(view); //On lance le thread de rendu rend.Launch(); while(App.IsOpened()) { sf::Event Event; while (App.GetEvent(Event)) //On parcourt la pile des venements { if (Event.Type==sf::Event::Closed) { App.Close(); } else if(Event.Type==sf::Event::MouseWheelMoved) //Zoom/Dzoom la molette de souris { if(Event.MouseWheel.Delta>0) { view.Zoom(1.5); } else { view.Zoom(0.75f); } } else if(Event.Type==sf::Event::KeyPressed) //Dplacement { if(Event.Key.Code == sf::Key::Left) { view.Move(-10,0); } else if(Event.Key.Code == sf::Key::Right) { view.Move(10,0); } else if(Event.Key.Code == sf::Key::Up) { view.Move(0,-10); } else if(Event.Key.Code == sf::Key::Down) { view.Move(0,10); } } } if(clock.GetElapsedTime()>time) //Si suffisament de temps s'est coul depuis le dernier affichage { clock.Reset(); mutex.Lock(); //On verouille l'image App.Draw(spr); //On l'affiche App.Display(); //On rafraichit l'cran mutex.Unlock(); //On rend la main au thread de rendu } } threadRun=false; //Avant de quitter, il faut penser stopper

13/19

www.siteduzero.com

Dessiner la fractale de Mandelbrot


le thread de rendu. } return 0;

14/19

Faire des zooms sur l'image


tant donn que la question m'a t poss plusieurs reprises, je vais vous expliquer comment faire pour zoomer sur l'ensemble de mandelbrot. Globalement, il n'y a pas de technique particulire pour obtenir un zoom sur une zone de la fractale, il s'agit juste de changer certains paramtres. Le tout, c'est de savoir lesquels changer et de quel manire.

Le zoom
Le premier paramtre que l'on aurais tendance changer si on veut zoomer, c'est le zoom (logique ). Donc oui, il faut l'augmenter, mais si on n'augmente que le zoom, on va se retrouver avec une image d'autant plus grand (et donc plus longue calculer) que on aura augment le zoom, et ce n'est pas forcment ce que l'on veut.

Les coordonns du plan complexe


Les quatre premiers paramtres que l'on dfinit sont les coordonns de la zone que l'on veut tracer. V quoi ils correspondent oici : x1 correspond la limite gauche de l'image x2 correspond la limite droite de l'image y1 correspond la limite du haut de l'image y2 correspond la limite du bas de l'image Par exemple, si on augmente x1, l'image sera plus petite vers la droite. En diminuant x2, l'image sera petite vers la gauche. Et de mme pour y1 et y2.

Le nombre d'itration maximum


Enfin, le nombre d'itration maximum est aussi important faire augmenter quand on zoom beaucoup, car plus on zoom, plus il faut tre prcis. Pour illustrer ce que l'on a vu au dessus, si je vous demande une image de quart en haut droite de la fractal de la mme taille que les autres images, il faudra : doubler le zoom, augmenter x1, diminuer y2 et un peu augmenter le nombre maximum d'itration. On obtient donc : zoom = 200 x1 = -0.75 y2 = 0 iteration_max = 100

Et voici le rsultat :

www.siteduzero.com

Dessiner la fractale de Mandelbrot

15/19

De mme si vous voulez zoomer sur un point du plan complexe de coordonn (x; y) en particulier, il faudra juste dfinir x1 = x-h, x2 = x+h, y1 = y-h et y2 = y+h. Avec h un valeur que vous fixerez vous-mme en sachant que plus elle est petite, plus vous zoomerez sur ce point en particulier. Bien videment, il faudra augmenter en consquence le zoom et le nombre d'itrations.

Pour aller plus loin


Maintenant que vous avez les bases pour crer la fractale de mandelbrot, dites-vous qu'il y a un bon nombre de fractales qui sont bass sur le mme principe.

Les ensembles de Julia


Les ensembles de Julia sont bass sur le mme principe que l'ensemble de Mandelbrot. La formule est exactement la mme ( ), seul les valeurs de dpart changent : sera un nombre complexe fixe de votre choix (essayer de le prendre dans le plan complexe de l'ensemble de Mandelbrot) et . La premire fractale montre dans le tutoriel est un ensemble de Julia. Sachez que si est situ dans la fractale de Mandelbrot, alors l'ensemble de Julia sera connexe, c'est--dire que la fractale sera d'un bloc. Alors que si n'est pas dans la fractale de Mandelbrot, l'ensemble de Julia sera forme de points non connects. V l'algorithme : oici Code : Autre dfinir dfinir dfinir dfinir dfinir dfinir x1 = -1 x2 = 1 y1 = -1.2 y2 = 1.2 zoom = 100 iteration_max = 150

dfinir image_x = (x2 - x1) * zoom dfinir image_y = (y2 - y1) * zoom Pour x = 0 tant que Pour y = 0 tant dfinir c_r dfinir c_i dfinir z_r dfinir z_i dfinir i = x < image_x par pas de 1 que y < image_y par pas de 1 = 0.285 = 0.01 = x / zoom + x1 = y / zoom + y1 0

Faire dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i i = i+1 Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max si i = iteration_max dessiner le pixel de coordonn (x; y)

www.siteduzero.com

Dessiner la fractale de Mandelbrot


finSi finPour finPour

16/19

C'est les valeurs de c_r et c_i qui vont dterminer la forme de l'ensemble. Avec les valeurs que j'ai mises dans l'algorithme, vous devriez obtenir la mme forme que l'ensemble de julia prsent dans l'introduction. Notez aussi que les ensembles de julia sont centrs sur lorigine du repre, donc il faut modifier les coordonns de x1, x2, y1 et y2 en consquence. Si vous prenez (-1.5; 1.5) pour x et y, vous devriez toujours avoir l'ensemble en entier. V ous pouvez aussi rajouter des couleurs de la mme manire que pour l'ensemble de Mandelbrot. V ce que j'obtient avec oil exactement le mme dgrad que pour l'ensemble de mandelbrot :

Buddhabrot
V une fractale qui a vraiment fait parler d'elle. En effet, elle ressemble beaucoup un bouddha en train de mditer. Si vous oil voulez des exemples sur internet, vous pouvez en trouver beaucoup. La mthode de gnration est proche de celle de la fractale de Mandelbrot, la diffrence prt qu'au lieu de dessiner les points appartenant l'ensemble de Mandelbrot, on va dessiner le chemin pris par la suite avant quelle diverge (que son module ne dpasse pas 2). Dans ce tutoriel, on parcourra tous les points de l'image, mais en thorie on devrais prendre les points au hasard sur le plan complexe. Un petit code pour que vous compreniez mieux : Code : Autre dfinir dfinir dfinir dfinir dfinir dfinir x1 = -2.1 x2 = 0.6 y1 = -1.2 y2 = 1.2 zoom = 100 iteration_max = 100

dfinir image_x = (x2 - x1) * zoom dfinir image_y = (y2 - y1) * zoom

// un tableau que l'on va incrmenter chaque fois que la suite Z_n passera par un po dfinir pixels comme un tableau 2D de image_x cases sur image_y cases avec toutes les

// en thorie, on devrait faire une seul boucle dans laquelle on devrait prendre les c Pour x = 0 tant que x < image_x par pas de 1 Pour y = 0 tant que y < image_y par pas de 1 dfinir c_r = x / zoom + x1 dfinir c_i = y / zoom + y1 dfinir z_r = 0 dfinir z_i = 0 dfinir i = 0 dfinir tmp_pixels comme une liste de coordonnes Faire

www.siteduzero.com

Dessiner la fractale de Mandelbrot

17/19

dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i i = i+1 ajouter les coordonnes ((z_r-x1)*zoom; (z_i-y1)*zoom) au tableau tmp_pixe Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max si i != iteration_max Pour chaque valeurs pixel de tmp_pixels si la case pixels[pixel[0]][pixel[1]] existe on incrmente la case en question finSi finPour finSi finPour finPour

Pour chaque case de coordonne (x; y) de l'image Dessiner le pixel de coordonne (x; y) avec la couleur rgb(min(pixels[x][y], 255), finPour

Avec ce code, plus la suite passe par un point, plus il sera clair. V le rsultat que j'obtient (aprs quelques modifications oici des paramtres et une rotation de 90 vers la droite) :

Comme vous pouvez le voir, c'est beaucoup plus long que pour la gnration de la fractale de Mandelbrot, mais c'est en partie due une augmentation de la taille et du nombre d'itrations. Pour avoir des couleurs, la plupart du temps, on crer un tableau par partie de la couleur (rouge, vert et bleu) et on change le nombre d'itration maximal pour chaque tableau. Il faut de grandes diffrences entre les itrations max pour avoir rellement de la couleur. Comme je sens que vous n'avez pas tout compris, je vous donne l'algorithme : Code : Autre dfinir dfinir dfinir dfinir dfinir dfinir dfinir dfinir dfinir x1 = -2.1 x2 = 0.6 y1 = -1.2 y2 = 1.2 zoom = 100 iteration_rouge = 100 iteration_vert = 1000 iteration_bleu = 10000 iteration_max = max(iteration_rouge, iteration_vert, iteration_bleu)

dfinir image_x = (x2 - x1) * zoom

www.siteduzero.com

Dessiner la fractale de Mandelbrot


dfinir image_y = (y2 - y1) * zoom

18/19

dfinir pixels_rouge comme un tableau 2D de image_x cases sur image_y cases avec toute dfinir pixels_vert comme un tableau 2D de image_x cases sur image_y cases avec toutes dfinir pixels_bleu comme un tableau 2D de image_x cases sur image_y cases avec toutes

// en thorie, on devrait faire une seul boucle dans laquelle on devrait prendre les c Pour x = 0 tant que x < image_x par pas de 1 Pour y = 0 tant que y < image_y par pas de 1 dfinir c_r = x / zoom + x1 dfinir c_i = y / zoom + y1 dfinir z_r = 0 dfinir z_i = 0 dfinir i = 0 dfinir tmp_pixels comme une liste de coordonnes

Faire dfinir tmp = z_r z_r = z_r*z_r - z_i*z_i + c_r z_i = 2*z_i*tmp + c_i i = i+1 ajouter les coordonnes ((z_r-x1)*zoom; (z_i-y1)*zoom) au tableau tmp_pixe Tant que z_r*z_r + z_i*z_i < 4 et i < iteration_max si i < iteration_rouge Pour les iteration_rouge premires valeurs pixel de tmp_pixels si la case pixels_rouge[pixel[0]][pixel[1]] existe on incrmente la case en question finSi finPour finSi si i < iteration_vert Pour les iteration_vert premires valeurs pixel de tmp_pixels si la case pixels_vert[pixel[0]][pixel[1]] existe on incrmente la case en question finSi finPour finSi si i < iteration_bleu Pour les iteration_bleu premires valeurs pixel de tmp_pixels si la case pixels_bleu[pixel[0]][pixel[1]] existe on incrmente la case en question finSi finPour finSi finPour finPour

Pour chaque pixel de coordonne (x; y) de l'image Dessiner le pixel de coordonne (x; y) avec la couleur rgb(min(pixels_rouge[x][y], finPour

V oil, c'est quand mme un brin plus compliqu que pour la fractale de Mandelbrot . Ne soyez donc pas tonn de ne pas comprendre a du premier coup, sachant que j'ai moi-mme mis pas mal de temps comprendre comment il fallait faire. Et il n'y a pas d'image cette fois-ci car je n'ai pas russi avoir un truc correcte vous prsenter, si vous voulez trouvez des images, faite la recherche "buddhabrot" sur google image, vous aurez plein d'images.

Mandelblub
Le Mandelblub est un essai de transformation de la fractale de Mandelbrot en 3D. tant donn que cela dpasse largement mes comptences, je vais vous laisser 2 liens qui permettront aux plus gourmands d'entre vous de satisfaire leur apptit. Le premier est un article en anglais sur le Mandelblub, il prsente de trs nombreuses images de cette fractale, vous pourrez donc apprcier la page sans connaitre un mot d'anglais : http://www.skytopia.com/project/fractal/mandelbulb.html. Le deuxime est un article en franais qui explique en dtail la dfinition du mandelblub et qui donne mme une technique de

www.siteduzero.com

Dessiner la fractale de Mandelbrot


rendu 3D pour les fractales : http://images.math.cnrs.fr/Mandelbulb.html Nous voici la fin du tutoriel. V ous devriez tre maintenant capable de dessiner des fractales en connaissant leur formule. Si vous n'avez pas compris un point ou qu'il vous semble obscure, merci de me le signaler afin que ce tutoriel soit le plus accessible possible.

19/19

Partager

www.siteduzero.com

S-ar putea să vă placă și