TD H4 : Fougère de Barnsley (énoncé)¶

L'objectif de ce TD est de comprendre comment dessiner la fractale bien connue sous le nom de fougère de Barnsley :

barnsley.png

Exercice 1 : on prépare le terrain, suite récurrente¶

On considère la suite de points $M_n(x_n,y_n)$ avec $M_0(1,1)$ et : $$ \begin{cases} x_{n+1} = x_n \text{ si } n \text{ est pair }\\ x_{n+1} = -1.1 x_n \text{ sinon} \end{cases} $$ et $$ \begin{cases} y_{n+1} = -1.1y_n \text{ si } n \text{ est pair }\\ y_{n+1} = y_n \text{ sinon} \end{cases} $$

Compléter le code de la fonction suivante qui renvoie les listes des valeurs de $(x_n)$ et $(y_n)$ pour $n$ de 0 à 50.

Rappel : en python pour accéder au dernier élément d'une liste L on peut utiliser L[-1].

In [1]:
def suites(n_points=50):
    x , y =[1], [1]
    for n in range(n_points):
        if # à compléter...
        
        
    return x,y

Écrire un code python permettant de dessiner les points $M(x_n,y_n)$ pour $n$ entre 0 et 50

In [3]:
import matplotlib.pyplot as plt

plt.figure(1)
plt.clf()

# à compléter

plt.show()

Exercice 2 : random¶

On donne ci-dessous une fonction python rand1(p1) qui renvoie 1 avec la probabilité $p1$ et 2 sinon :

In [4]:
from random import random
# rappel : random() renvoie un nombre aléatoire entre 0 et 1

def rand1(p1):
    r = random()
    if r<p1 : 
        return 1
    else :
        return 2

Q1. En s'inspirant du code précédent, écrire une fonction python rand2(p1,p2) qui renvoie 1 avec la probabilité $p1$, 2 avec la propbabilité $p_2$ et 3 sinon.

In [ ]:
def rand2(p1,p2):
    r = random()
    # à compléter
    

Q2. On souhaite généraliser cela à un nombre quelconque de probas. Écrire alors une fonction rand(lst : list) qui réçoit une liste de nombres compris entre 0 et 1, représentant des probabilités $p_1$, $p_2$, ... et qui renvoie 1 avec la probabilité $p_1$, 2 avec la probabilité $p_2$ et ainsi de suite. Il faut aussi s'assurer que la somme des $p_i$ est bien inférieure à 1.

In [36]:
# un peu plus dur !

from random import random

def rand(lst : list) -> int:
    

# exemple d'exécution :
print(rand([0.5,0.1,0.3]))
3

Exercice 3 : fougère de Barnsley¶

Q3 A partir du point de coordonnées $(x_0,y_0)=(0.5,0)$ construire l’ensemble des 30 000 points $(x_n , y_n )$ tels que : $$ x_{n+1}=\left\{ \begin{array}{ll}0.5 & \text{avec une probabilité de 2%}\\ -0.139*x_n+0.263*y_n+0.57 & \text{avec une probabilité de 15%} \\ 0.17*x_n-0.215*y_n + 0.408 & \text{avec une probabilité de 13%} \\ 0.781*x_n + 0.034*y_n + 0.1075 & \text{avec une probabilité de 70%} \end{array}\right. $$ et $$ y_{n+1}=\left\{ \begin{array}{ll}0.27*y_n & \text{avec une probabilité de 2%}\\ 0.246*x_n+0.224*y_n-0.036 & \text{avec une probabilité de 15%} \\ 0.22*x_n + 0.176*y_n + 0.0893 & \text{avec une probabilité de 13%} \\ -0.032*x_n + 0.739*y_n + 0.27 & \text{avec une probabilité de 70%} \end{array}\right. $$

In [37]:
import matplotlib.pyplot as plt
from random import random

def rand(lst : list) -> int:
    """ Cette fonction reçoit une liste [p1,p2,... ] de nombres entre 0 et 1
    et renvoie 1 avec la proba p1, 2 avec la proba p2 etc..."""
    assert sum(lst) < 1 # la somme des probas doit etre inférieure à 1
    r = random()
    p = 0
    n = 0
    for i in lst :
        p = p+i
        n = n + 1
        if r < p :
            return n
    return n+1

def suites(n_points):
    x , y = [0.5] , [0]
    
    # à compléter
        
    return x,y
            


plt.figure(2)
plt.clf()

x,y = suites(30000)
plt.plot(x,y,
        linestyle = ' ',
        marker='.',
        markersize=1,
        markeredgecolor = 'g')
plt.show()