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 :
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].
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
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 :
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.
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.
# 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. $$
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()