Récursivité
Transcription
Récursivité
Récursivité Figures fractales Exemple : des « arbres » ... On cherche à construire un « arbre », caractérisé par la longueur L de son tronc et la « profondeur » p du tracé. La forme des arbres construits est déterminée par des constantes illustrées à la profondeur 2 : ➢ rap_g et rap_d sont les rapports par lesquels multiplier la longueur d'une « branche » pour trouver celle de la « branche » suivante, à gauche ou à droite. Le tronc est considéré comme l'une des branches. ➢ ang_g et ang_d sont les angles (non orientés, en degré) formés par les branches à la génération suivante, par rapport à l'axe courant (celui de la branche actuelle), à gauche ou à droite. Voici une fonction récursive (algorithme en langage naturel) qui permet de répondre à la question : fonction arbre(L,p): On trace un segment de longueur L, le tronc (cap actuel de la tortue conservé). Si la profondeur est supérieure à 1, À partir de ce point on tourne d'un angle ang_g dans le sens anti-horaire, et on trace l'arbre dont le tronc mesure rap_g×L à la profondeur p–1 c'est-à-dire arbre(rap_g×L, p-1) On tourne dans le sens horaire de ang_g + ang_d (on forme donc un angle de ang_d dans le sens horaire par rapport au cap initial) et on trace l'arbre codé : arbre(rap_d×L, p–1). on tourne dans le sens anti_horaire de ang_d (pour récupérer le cap initial) On recule de L (pour se retrouver à la position initiale). Faites fonctionner mentalement cet algorithme, avec p = 1, puis p = 2. Traduction en Python 3, en utilisant le module turtle pour tracer des figure comme en langage Logo : from turtle import * ### Paramètres : speed("fastest") # ou "fast", "normal", etc. ou de 1 à 10... color("blue", "orange") # couleur du tracé / du fond si l'on colorie ang_d = 38 # rap_d = 0.6 # À modifier pour modifier la forme de l'arbre... ang_g = 30 # rap_g = 0.5 # Long = 200 # ### Fonction récursive de tracé de l'arbre : def arbre(L, p): """ Tracé de l'arbre au tronc de longueur L à la profondeur p En début de tracé, on est au pied du tronc, à la fin on est à son sommet, et le 'cap' de la souris est le même.""" down() forward(L) if (p > 1): left(ang_g) arbre(L*rap_g, p-1) right(ang_d + ang_g) arbre(L*rap_d, p-1) left(ang_d) up() back(L) ###### Programme principal ###### ### Saisie de la profondeur : p=int(numinput("Dessin fractal", "Profondeur : ", 8, minval=1, maxval=20)) if (p == None): # "annulé", au lieu d'une saisie numérique exit() ### Placement initial de la tortue et affichage de la profondeur : up() setposition(0,-Long*1.2) write("Profondeur %d"%p, align="center", font=('Arial',14)) setposition(0,-Long) left(90) # Au départ, la tortue part vers la droite, donc on redresse le cap... arbre(Long, p) hideturtle() done() Documentation de référence pour le module turtle : http://docs.python.org/3.2/library/turtle.html À présent, vous aller construire quelques figures fractales. Prenez le temps d'écrire un algorithme en langage naturel et de le vérifier avec soin (« cap » de la tortue notamment) avant de passer à la programmation. Flocon de Von Koch Activité d'échauffement : tracez un triangle équilatéral de côté L = 250. En bonus : centrez-le dans la fenêtre. Ensuite, réalisez le flocon de Von Koch basé sur un triangle équilatéral de côté L, au niveau de profondeur p : ➢ Au niveau 0 de profondeur, chaque « côté » est un segment de longueur L. ➢ À un niveau non nul donné, on remplace chaque « côté » par quatre « côté » de longueur L/3 chacun, tels que les deux centraux et celui de longueur L/3 indiqué en pointillés (non tracé) forment un triangle équilatéral du côté extérieur de la figure. Et chaque « côté » lui-même est remplacé lui-même par cet ensemble de quatre « côtés » de niveau de profondeur inférieur... L L On utilisera la récursivité pour le tracé du « coté », déterminé par sa longueur et le niveau de profondeur. En pseudo-code, cela peut s'écrire : côté(L, p) : Si p vaut 0 : Tracer le segment de longueur L (avec le cap courant de la tortue) Sinon : Tracer le côté(L/3, p-1) (avec le cap contant) Tourner « vers gauche » de 60° Tracer le côté(L/3, p-1) Tourner vers la droite de 120°, etc. Voici donc le fameux flocon, pour les niveaux 0, 1, 2, 3, puis 4. Le coloriage s'effectue de la manière suivante, en Python 3 : en début de programme, begin_fill() initialise le coloriage, qui sera effectué à l'appel de end_fill() Bonus : en construisant les triangles vers l'intérieur, vous obtiendrez aussi de belles figures... Carrés imbriqués Au niveau 1 de profondeur, on trace un simple carré ; au niveau 2, on ajoute à l'intérieur un carré dont les sommets sont les milieux des côtés du précédent, et ainsi de suite. Ainsi, au niveau 5, on doit obtenir la figure ci-dessous. On s'impose ici de ne jamais lever le crayon ni repasser deux fois au même endroit durant le tracé ! [Besoin d'une astuce ? Voir en fin de document...] Pour le coloriage on crée une fonction spécifique, dont les arguments (non utilisés ici) sont les coordonnées x et y de la tortue : def colorier(x,y): end_fill() Puis en fin de tracé, de manière à l'associer au clic sur le fond, on ajoute : onscreenclick(colorier) Triangle de Sierpinski À construire d'abord sans colorier. Voici les premiers niveaux de profondeur (1, 2, 3, puis 4 et enfin 5 colorié) :