Aller au contenu

🐢 Arbre fractal⚓︎

On souhaite avoir une fonction arbre qui permet de dessiner une figure comme celle-ci.

Question 1

Compléter le code suivant :

🐍 Script Python
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
🐍 Script Python
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
🐍 Script Python
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 entre 0.4 et 0.9 ;
  • les deux angles auront, chacun, une magnitude aléatoire entre 20 et 70, 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 :

🐍 Script Python
from random import randrange

x = randrange(200, 3400) / 1000

Pour obtenir un signe alterné dans une boucle, on peut écrire

🐍 Script Python
signe = +1
for ... in ...:
    signe = - signe  # changement de signe
    ...
Réponse
🐍 Script Python
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.