🐢 Arbre fractal⚓︎
On souhaite avoir une fonction arbre
qui permet de dessiner une figure comme celle-ci.
Question 1
Compléter le code suivant :
import turtle
def tronc(a: float):
"Dessine un tronc de longueur a"
# version basique
turtle.pensize(a * 1/3)
turtle.forward(a)
def arbre(a: float, n: int):
"""Si n > 0:
- Dessine un arbre ayant un tronc de longueur a,
- et deux branches qui seront des arbres
- de niveau n - 1,
- de taille réduite d'un facteur `k = 0.75`
- et orientées à 45°, de part et d'autre du tronc.
La tortue retrouve sa position et son orientation initiale !
"""
k = 0.75 # coefficient de réduction
... # À compléter
turtle.speed(1) # de 1 (lent) à 11 (rapide)
turtle.left(90) # pour regarder vers le haut
turtle.penup()
turtle.backward(100) # recule de 100
turtle.pendown()
arbre(80, 8)
turtle.done()
Indice 1
Dans la fonction arbre
, il y a :
- un seul appel à
tronc
- deux appels récursifs à
arbre
- plusieurs changements d'orientation.
Testez vos changements de direction et de position avec un crayon !
N'oubliez pas de repositionner la tortue, comme au départ !
Réponse
def arbre(a: float, n: int):
"""Si n > 0:
- Dessine un arbre ayant un tronc de longueur a,
- et deux branches qui seront des arbres
- de niveau n - 1,
- de taille réduite d'un facteur `k = 0.75`
- et orientées à 45°, de part et d'autre du tronc.
La tortue retrouve sa position et son orientation initiale !
"""
k = 0.75 # coefficient de réduction
if n > 0:
tronc(a)
turtle.left(45)
arbre(k * a, n - 1)
turtle.right(90)
arbre(k * a, n - 1)
turtle.left(45)
turtle.penup()
turtle.backward(a) # retour au départ
turtle.pendown()
Question 2
Factoriser le code, en faisant une boucle avec un tour pour chaque branche.
Indice 2
On pourra décomposer le turtle.right(90)
central en deux rotations.
On pourra utiliser une boucle sur [-45, +45]
qui fera 3 instructions.
Réponse
def arbre(a: float, n: int):
"""Si n > 0:
- Dessine un arbre ayant un tronc de longueur a,
- et deux branches qui seront des arbres
- de niveau n - 1,
- de taille réduite d'un facteur `k = 0.75`
- et orientées à 45°, de part et d'autre du tronc.
La tortue retrouve sa position et son orientation initiale !
"""
k = 0.75 # coefficient de réduction
if n > 0:
tronc(a)
for angle in [-45, +45]:
turtle.left(angle)
arbre(k * a, n - 1)
turtle.right(angle)
turtle.penup()
turtle.backward(a) # retour au départ
turtle.pendown()
Question 3
On souhaite introduire de l'aléatoire pour chaque branche :
- le coefficient
k
sera un nombre aléatoire entre0.4
et0.9
; - les deux angles auront, chacun, une magnitude aléatoire entre
20
et70
, et des signes distincts.
Modifiez votre script en ce sens.
Indice 3
Pour avoir un nombre aléatoire entre 0.2
et 3.4
, on peut faire simplement :
from random import randrange
x = randrange(200, 3400) / 1000
Pour obtenir un signe alterné dans une boucle, on peut écrire
signe = +1
for ... in ...:
signe = - signe # changement de signe
...
Réponse
from random import randrange
def arbre(a: float, n: int):
"""Si n > 0:
- Dessine un arbre ayant un tronc de longueur a,
- et deux branches qui seront des arbres
- de niveau n - 1,
- de taille réduite d'un facteur `k` aléatoire,
- et orientées de part et d'autre du tronc.
La tortue retrouve sa position et son orientation initiale !
"""
if n > 0:
tronc(a)
signe = +1
for _ in range(2):
signe = - signe
k = randrange(400, 900) / 1000
angle = randrange(20000, 70000) / 1000
turtle.left(signe * angle)
arbre(k * a, n - 1)
turtle.right(signe * angle)
turtle.penup()
turtle.backward(a) # retour au départ
turtle.pendown()
TODO, à finir
Question 4
On souhaite introduire de l'aléatoire pour dessiner le tronc.
Au lieu d'aller tout droit, on souhaite décomposer en plusieurs petits pas de tortue avec de légers changements d'orientation, et de légers changements d'épaisseur.
Question 5
On souhaite qu'un tronc soit dessiné en 3 ou 4 traits plus fins, avec une couleur légèrement variable sur un même tronc, et de plus en plus claire avec la profondeur.