Informatique - TP n◦ 8 Claude Bernard 2013-2014 QUELQUES FRACTALES Une fractale est une figure géométrique dont la structure est invariante par changement d’échelle, i.e. telle qu’un zoom sur une partie ressemble au tout (on parle d’auto-similarité). Le but de ce TP est d’obtenir, à l’aide de Python, des approximations de différentes fractales. Vous travaillerez dans des fichiers scripts différents pour chacune des deux parties de ce TP, enregistrés sous un nom intelligible dans un sous-répertoire de votre répertoire de travail. 1 Les flocons de Koch On obtient une fractale, appelée flocon de Koch, en partant d’une ligne brisée L quelconque (souvent un triangle équilatéral) et en répétant à l’infini l’opération qui consiste à ajouter au milieu de chaque arête AB de L un triangle équilatéral de côté 31 AB : → → → ··· → Dans ce qui suit, on appellera flocon d’ordre k de L la ligne brisée obtenue à partir de L après k répétitions de l’opération décrite ci-dessus. 1.1 Affichage d’une première ligne brisée 1. Importer les librairies math et matplotlib.pyplot. 2. Affichage d’une ligne brisée en Python. a. Définir les listes X1 et Y1 respectivement des abscisses et des ordonnées des sommets d’un triangle équilatéral. [On pourra penser aux racines cubiques de l’unité.] b. Afficher le triangle ainsi défini, à l’aide de la suite de commandes suivantes : X1, Y1 = ... plot(X1,Y1) axis(’equal’) show() # # # # Les listes X1 et Y1 demandées en 2a On calcule les données du dessin On ajoute une option pour orthonormaliser le repère On ouvre une fen^ etre graphique contenant le dessin voulu Si le résultat est conforme à vos attentes, fermez la fenêtre graphique, effacez (ou commentez) les trois dernières lignes relatives à ce dessin dans votre fichier script, et passez à la suite. 1.2 Calcul d’un flocon 3. (Bonus) Préliminaires mathématiques. On munit le plan d’un repère orthonormal direct. Soient AB une arête de L et CDE le triangle équilatéral ajouté au milieu de AB lors du calcul du flocon d’ordre un de L : B D E C A Vérifier que si A x1 y1 ,B x2 y2 et x y = x2 −x1 y2 −y1 , alors C x1 + x3 , y1 + y3 y √ 2 3 y x y1 + 2 − √ 2 3 x1 + x2 + et E x1 + 2x 3 . y1 + 2y 3 x − → − [On rappelle que le vecteur → v −y est directement orthogonal à u x y .] 1/4 D Informatique - TP n◦ 8 Claude Bernard 2013-2014 4. Implémentation Python. a. Écrire une fonction pointe(x1,y1,x2,y2) prenant en arguments les coordonnées de deux points A et B du plan, et renvoyant les deux listes respectivement des abscisses et des ordonnées des points C, D, E et B dans cet ordre, comme calculées en 3. b. Tester cette fonction pointe sur quelques exemples. En particulier, on doit obtenir : >>> pointe(1,0,1,3) ([1.0, 1.8660254037844388, 1.0, 1], [1.0, 1.5, 2.0, 3]) c. À l’aide de la fonction pointe de 4a et d’une boucle for, écrire une fonction flocon(X,Y) prenant en arguments les listes respectivement des abscisses et des ordonnées des sommets d’une ligne brisée L, et renvoyant les listes des abscisses et des ordonnées des sommets du flocon d’ordre un de L. d. Tester cette fonction sur les listes X1 et Y1 définies en 2a. Si l’affichage du résultat de la commande flocon(X1,Y1) est conforme à vos attentes, vous pouvez passer à la suite. 5. Affichage d’un flocon. a. Calculer (à l’aide de Python) les listes X et Y des abscisses et des ordonnées du flocon d’ordre cinq du triangle équilatéral défini par les listes X1 et Y1 de 2a. b. Afficher ce flocon. Rq. Vous pouvez donner un titre au dessin, et enregistrer l’image ainsi obtenue, en ajoutant les options title("Un joli flocon") et savefig("flocon.png") avant la commande show(). 6. Animation des premières étapes de construction. Effacez (ou commentez) le code relatif à 5b dans votre fichier script. En y reportant et en complétant le code ci-dessous, obtenir l’animation des cinq premières étapes de construction du flocon de Koch. X,Y = ... p=plot(X,Y)[0] axis(’equal’) # on stocke dans p les données du dessin for k in ... pause(1) X,Y = ... p.set_data(X,Y) # on admire le résultat pendant 1s # on met à jour X et Y # on met à jour les données du dessin show() 1.3 (Bonus) Des flocons carrés Reprendre la démarche de cette première partie en remplaçant les triangles par des carrés, pour obtenir des flocons et une animation de type : → → → 2/4 ··· → Informatique - TP n◦ 8 Claude Bernard 2013-2014 2 Les ensembles de Mandelbrot et de Julia On considère la suite complexe (zn )n∈N , dépendant d’un paramètre c ∈ C, définie par : z0 ∈ C et zn+1 = zn2 + c pour tout n ∈ N. On s’intéresse dans ce qui suit au caractère borné (ou non) de cette suite, en fonction de c et z0 . • L’ensemble de Mandelbrot est l’ensemble des nombres complexes c pour lesquels la suite (zn )n∈N de premier terme z0 = 0 et de paramètre c est bornée. • L’ensemble de Julia associé à c ∈ C est l’ensemble des complexes z0 ∈ C pour lesquels la suite (zn )n∈N de premier terme z0 et de paramètre c est bornée. 2.1 Préliminaires 7. (Bonus) Préliminaires mathématiques. On pose m = max(2, |c|) et D2 = {z ∈ C | |z| 6 2}. a. Montrer que s’il existe p ∈ N tel que |zp | > m, alors la suite (zn )n∈N n’est pas bornée. [Fixer ε ∈ R∗+ tel que ε < |zp | − m et montrer que |zp+1 | > |zp |(1 + ε). En déduire que ∀ n ∈ N∗ , |zp+n | > |zp |(1 + ε)n , et conclure.] b. En déduire que l’ensemble de Mandelbrot, et les ensembles de Julia associés à c ∈ D2 , sont inclus dans D2 . 8. Test du caractère borné de la suite (zn )n∈N . Vu 7, la suite (zn )n∈N est bornée si et seulement si tous ses termes sont de module inférieur à m = max(2, |c|). Comme il n’est bien sûr pas possible, sur machine, de calculer l’infinité des termes zn , on considèrera dans ce qui suit que la suite (zn )n∈N est bornée si ses 100 premiers termes sont de module inférieur à m. a. Écrire une fonction rang_de_sortie(c,z0) prenant en argument deux complexes c et z0 et renvoyant, dans la suite (zn )n∈N de premier terme z0 et de paramètre c, le plus petit indice p ∈ [[0; 99]] tel que |zp | > m, s’il existe, ou renvoyant 100 sinon. b. Tester cette fonction sur quelques exemples. En particulier, on doit obtenir : >>> rang_de_sortie(1,0) 3 >>> rang_de_sortie(0,1j) 100 Ainsi, les suites (zn )n∈N bornées ont un “rang de sortie” égal à 100, et on considère par abus dans ce qui suit que la réciproque est vraie. 9. Affichage graphique d’une matrice. La méthode utilisée en 2.2 et 2.3 ci-dessous pour visualiser les ensembles de Mandelbrot et de Julia, fait appel à la commande matshow de la librairie matplotlib.pyplot, qui permet de visualiser en couleurs le contenu d’une matrice (objet de type array en Python). a. Charger les librairies numpy et matplotlib.pyplot. Consulter l’aide sur la commande zeros de la librairie numpy. b. À l’aide de la commande zeros et d’une boucle for, définir la matrice diagonale D de taille 100 dont le coefficient diagonal d’indice (j, j) vaut j + 1. [On accède au coefficient (j, k) d’une matrice D par la commande D[j,k], en se rappelant que la numérotation en Python commence à 0.] c. Visualiser la matrice D de 9b, par les commandes suivantes : D = ... matshow(D) show() # Définition de D # On calcule les données du dessin # On ouvre une fen^ etre graphique contenant le dessin voulu Interpréter : en quelle couleur est représenté un coefficient égal à 0 ? à 100 ? 3/4 Informatique - TP n◦ 8 Claude Bernard 2013-2014 2.2 L’ensemble de Mandelbrot Stratégie. Pour obtenir une représentation (approximative) de l’ensemble de Mandelbrot : • On fixe l’entier N = 400, qui sera la résolution de notre dessin. • On crée un quadrillage régulier de l’ensemble C des complexes de parties réelle et imaginaire dans [−2; 2] (dans lequel l’ensemble de Mandelbrot est inclus, par 7), i.e. un ensemble de N 2 complexes zj,k , où j, k ∈ [[0; N − 1]], régulièrement répartis dans C. • On crée la matrice M carrée de taille N dont le coefficient d’indice (j, k) est le “rang de sortie” de la suite (zn )n∈N de premier terme z0 = 0 et de paramètre c = zj,k . • On visualise cette matrice M comme en 9c : l’ensemble de Mandelbrot, correspondant aux coefficients égaux à 100 dans cette matrice M , apparaı̂tra en rouge sur le dessin. 10. a. Consulter l’aide relative à la commande linspace de la librairie numpy. b. À l’aide de la commande linspace, définir deux listes X et Y de N points régulièrement espacés dans l’intervalle [−2; 2]. Les éléments de X iront en croissant, et ceux de Y en décroissant. 11. À l’aide de la commande zeros et de deux boucles for, créer une matrice M carrée de taille N , dont le terme d’indice (j, k) ∈ [[0; N − 1]]2 vaut rang_de_sortie(complex(X[k],Y[j]),0). 12. a. Afficher la matrice M. b. (Bonus) Zoomer sur une partie du dessin, en redéfinissant les listes X et Y, pour observer la propriété d’auto-similarité de l’ensemble de Mandelbrot. 2.3 (Bonus) Les ensembles de Julia Reprendre la démarche entreprise en 2.2 pour obtenir la représentation (approximative) de différents ensembles de Julia associés à différents complexes c ∈ D2 . Voici quelques valeurs de c à essayer, en se rappelant que i se note 1j en Python : • c = 0 (deviner l’ensemble de Julia correspondant), • c = 0.25, c = 0.26, c = 0.5, c = −0.5, c = −0.75, c = −1, • c = 0.5i, c = 0.64i, c = 0.65i, c = i, • c = −0.74 + 0.1i, c = −0.85 + 0.2i, c = −0.05 + 0.7i, c = −0.29 − 0.64i, c = −0.57 + 0.48i ... 4/4