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é) :