From a228f64a066f43cd63af7b35a17edf4e7a468cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Mogu=C3=A9rou?= Date: Thu, 17 Nov 2022 08:23:29 +0100 Subject: [PATCH] =?UTF-8?q?Transf=C3=A9rer=20les=20fichiers=20vers=20'102?= =?UTF-8?q?=5FFractales'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FractaleDeJulia_valentin_moguerou.ipynb | 846 ++++++++++++++++++ .../L-Systeme_EL-Valentin_Moguerou.ipynb | 491 ++++++++++ 2 files changed, 1337 insertions(+) create mode 100644 102_Fractales/FractaleDeJulia_valentin_moguerou.ipynb create mode 100644 102_Fractales/L-Systeme_EL-Valentin_Moguerou.ipynb diff --git a/102_Fractales/FractaleDeJulia_valentin_moguerou.ipynb b/102_Fractales/FractaleDeJulia_valentin_moguerou.ipynb new file mode 100644 index 0000000..4534a65 --- /dev/null +++ b/102_Fractales/FractaleDeJulia_valentin_moguerou.ipynb @@ -0,0 +1,846 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

  Tracer des fractales de Julia :  

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cette fois il s'agit de tracer des fractales, issues **des mathématiques et non de la nature** comme pour les Lsystem. \n", + "Gaston Maurice JULIA est un mathématicien du début du XX eme siècle. Il a travaillé sur les itérations de fonctions complexes. \n", + "Remarque: Il ne disposait pas alors d'ordinateur avec écran graphique pour représenter son travail ;-) \n", + "Dans les années 1970, Benoît MANDELBROT c'est intéressé aux travaux de JULIA et a inventé le terme de fractale. \n", + "Voir: https://fr.wikipedia.org/wiki/Ensemble_de_Mandelbrot\n", + "\n", + "![image](./images/julia.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

1/ Rappel: les équations du second degré :

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "La théorie développée par Julia est basée sur les nombres complexes. Ces derniers trouvent leur justification dans la résolution des équations du second degré : \n", + "$a.x² + b.x + c = 0$ \n", + "La résolution d'une telle équation se fait par le calcul de son discriminant : \n", + "$\\Delta = b² - 4.a.c$ \n", + "Le signe de ce dernier nous renseigne sur les solutions de l'équation: \n", + "$\\Delta > 0 \\rightarrow$ l'équation admet deux racines qui sont distinctes: $x_1 = (-b +\\sqrt \\Delta)/2.a$ et $x_2 = (-b -\\sqrt \\Delta)/2.a$ \n", + "$\\Delta = 0 \\rightarrow$ l'équation a pour solution une racine double: $x_1 = -b/2.a$ \n", + "$\\Delta < 0 \\rightarrow$ l'équation n'a pas de solution dans l'ensemble des réels: $\\mathbb{R}$ ... $\\Rightarrow$ mais peut-être dans un autre ensemble, tel que:$\\mathbb{C}$ " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En résumé: \n", + "![image](./images/Equation2degre.png)\n", + " \n", + "$\\Rightarrow$ Écrire un script permettant à partir d'une équation donnée par l'utilisateur, de préciser si cette équation a des solutions et leurs valeurs." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "L'ensemble des solutions est {2.6666666666666665, -5.0}.\n" + ] + } + ], + "source": [ + "'''Résolution de l'équation du 2° degré '''\n", + "\n", + "from math import sqrt\n", + "\n", + "def solve(a, b, c):\n", + " d = b**2 - 4*a*c\n", + " if d<0:\n", + " return set()\n", + " return {(-b-sqrt(d))/(2*a), (-b+sqrt(d))/(2*a)}\n", + "\n", + "a,b,c = (float(x.strip()) for x in input(\"aX² + bX + c = 0. Entrer a, b, c [format: 'a,b,c']\").split(','))\n", + "print(f\"L'ensemble des solutions est {solve(a,b,c)}.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

2/ Au secours Valentin : c'est quoi un nombre complexe ? De quoi on parle, tu nous expliques ?

\n", + "\n", + "Introduction à l'ensemble des complexes: $\\mathbb{C}$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "'''Les nombres complexes avec Python'''\n", + "\n", + "a = int(input('Saisir la partie réelle du nombre complexe z: '))\n", + "b = int(input('Saisir la partie imaginaire du nombre complexe z: '))\n", + "z = complex(a,b)\n", + "print(f'z = {z} \\n')\n", + "print(f'La partie réelle de z est : {z.real}')\n", + "print(f'La partie imaginaire de z est : {z.imag}i \\n')\n", + "print(f'Le module de z est : {abs(z)}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Ce qu'il faut retenir :

\n", + "\n", + "$\\Rightarrow$ Il existe un ensemble $\\mathbb{C}$ appelé ensemble des complexes, dans lequel l'ensemble des réels $\\mathbb{R}$ est inclus \n", + "Un complexe est définit par deux nombres réels : \n", + "le premier représente la partie réel du complexe, le deuxième sa partie imaginaire à laquelle est associée à la lettre i (ou j) : $z = -2 + 3i$ ou encore $z = -2 + 3j$ \n", + "\n", + "**Propriété de l'imaginaire i** : $~i^2 = -1$ (ou encore : $~j^2 = -1$). \n", + "C'est cette dernière propriété qui permet de résoudre le cas $\\Delta < 0$ pour les équations du 2° degré : \n", + "![image](./images/DeltaNegatif.png)\n", + "\n", + "Puisque d'un nombre complexe est constitué de deux parties (partie réelle et partie imaginaire), il est tentant de lui associé un point du plan de tel sorte que : \n", + "- sa partie réelle est portée par l'axe des abscisses (Ox) \n", + "- sa partie imaginaire est portée par l'axe des ordonnées (Oy). \n", + "\n", + "Ainsi au nombre complexe $z = a + bi$ correspond le point M de coordonnées a et b : $M(a, b)$. \n", + "On dit que : **z est l'affixe du point M**. \n", + "\n", + "Application: Utiliser le logiciel ```Geogebra``` (sélectionner le mode **Tableur** => voir menu *Affichage*) pour représenter dans **le plan complexe** les points d'affixe : \n", + "$z_1 = 2 + 3i; ~ z_2 = 1; ~ z_3 = -1i = -i$ (ne pas oublier de cocher dans Géogebra : *Afficher l'objet*).\n", + "\n", + "On constate que la distance du point M (affixe de z) à l'origine est donnée par : $\\sqrt{a^2 + b^2}$. \n", + "Cette distance représente aussi le module du nombre complexe $~z = a + ib$ : \n", + "$|z| = \\sqrt{a^2 + b^2}$\n", + "\n", + "![lien](http://www.jaicompris.com/image/playvideo.png)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

3/ Compléter votre algorithme sur la résolution d'une équation du 2° degré :
\n", + " => Ajouter le cas où le discriminant est négatif

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Le point maths, par Valentin\n", + "\n", + "## Théorème d'Alembert-Gauss\n", + "\n", + "Tout polynôme non constant à coefficients complexes admet une racine dans $\\mathbb{C}$.\n", + "\n", + "$\\boxed{\\forall P \\in \\mathbb{C}[X], \\deg P \\geqslant 1, \\exists z \\in \\mathbb{C} \\quad P(z) = 0}$\n", + "\n", + "On peut aussi dire que tout polynôme de $\\mathbb{C}[X]$ peut être factorisé, de la forme :\n", + "\n", + "$\\displaystyle P(X) = a_n\\prod_{k=1}^n (X - a_k)$ (où $n$ est le degré de $P$).\n", + "\n", + "Cela entraîne que la somme des multiplicités des racines distinctes d'un polynôme vaut le degré de ce polynôme.\n", + "\n", + "## Un cas particulier : $\\deg P = 2$\n", + "\n", + "Soit $P = aX^2 + bX + c$ et soit $\\Delta = b^2 - 4ac$.\n", + "\n", + "Soient $\\delta_1$ et $\\delta_2$ les deux racines carrées de $\\Delta$.\n", + "\n", + "Alors $z_1 = \\dfrac{-b-\\delta}{2a}$ et $z_2 = \\dfrac{-b+\\delta}{2a}$ vérifient $P(z_1) = 0$ et $P(z_2) = 0$\n", + "\n", + "Dans le cas où $z_1 = z_2$, on dit que $z_1$ est de multiplicité 2.\n", + "\n", + "Remarquons que $\\delta_1 + \\delta_2 = 0$.\n", + "\n", + "La fonction python sqrt du module cmath associe à un complexe $z$ une de ses deux racines carrées. Notons $\\delta$ une telle racine. Alors $\\{\\delta, -\\delta\\}$ est l'image de $z$ par la multifonction (i.e correspondance) qui à un complexe associe ses racines carrées. C'est aussi la coupe du graphe $\\{(x, y) \\in \\mathbb{C}^2 \\mid y^2 = x \\}$ suivant $\\{z\\}$. L'application $f: z \\mapsto z^2$ n'étant pas injective, la correspondance $f^{-1}$ n'est pas univoque." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{(-0.6180339887498949+0j), (1.618033988749895+0j)}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'''Résolution d'une équation du second degré dans l'ensemble des complexes'''\n", + "\n", + "from cmath import sqrt\n", + "\n", + "def solve(a, b, c):\n", + " d = b**2 - 4*a*c\n", + " return {(-b-sqrt(d))/(2*a), (-b+sqrt(d))/(2*a)}\n", + "\n", + "solve(1, -1, -1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

4/ Les suites de Julia :

\n", + "\n", + "Une **suite d'éléments de $E$** est une application de $\\mathbb{N}$ dans $E$. Ces suites sont soit définies explicitement, soit définies par récurrence.\n", + "Exemple: $u_{n+1} = u_n * 2 + 3$. On suppose ici que le terme initial est: $u_0 = 1$ :\n", + "- $u_0 = 1$\n", + "- $u_1 = 5$\n", + "- $u_2 = 13$\n", + "- ... \n", + "\n", + "Le calcul d'un terme n d'une suite, avec n très grand, peut-être long et fastidieux. \n", + "$\\Rightarrow$ La technologie numérique et les ordinateurs s'avèrent d'une grande aide pour le calcul des suites. \n", + "- Exemple 1 : La suite de Fibonacci, déjà rencontrée en exercice, pour laquelle l'élément $u_n$ dépend de $u_{n-1}$ et $u_{n-2}$ \n", + "$\\Rightarrow ~f_0 = 0; ~ f_1 = 1 ~~ \\Rightarrow ~ f_n = f_{n-1} + f_{n-2}$ \n", + "\n", + "- Exemple 2 : avec le programme du calcul du Lsystem : \n", + "$\\Rightarrow$ Voir le code ci-dessous : **mettre en évidence** la ligne permettant le ***calcul de la suite*** des termes du Lsystem: à l'aide d'un commentaire." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ordre 0 => A\n", + "ordre 1 => AB\n", + "ordre 2 => ABA\n", + "ordre 3 => ABAAB\n", + "ordre 4 => ABAABABA\n" + ] + } + ], + "source": [ + "def codage_lSystem(chaine: str, ordre: int) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne initiale (l'axiome) et l'ordre souhaité\n", + " Retourne la chaîne obtenue après n applications du L-system\n", + " \"\"\"\n", + " for n in range(ordre): # Itérer le lSystem jusqu'à l'ordre n\n", + " chaine = lSystem_convert(chaine)\n", + " return chaine\n", + "\n", + "def lSystem_convert(chaine: str) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne de caractères\n", + " Retourne la chaîne obtenue après application des règles du L-System\n", + " \"\"\"\n", + " rules = {'A': 'AB', 'B': 'A'} # A compléter : règles\n", + " return ''.join([rules[car] for car in chaine ]) \n", + "\n", + "axiome = 'A'\n", + "for k in range (5): # Pour affichage des générations jusqu'à l'ordre n\n", + " print(f'ordre {k} => {codage_lSystem(axiome, k)}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

5/ Les ensembles de Julia :

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Un ensemble de Julia $J(c)$ est défini à partir d'une suite ```complexe```, et consiste à voir si la suite $u_n$ \"s'échappe\" d'un domaine donné, lorsque n augmente. \n", + "Exemple : on considère la suite de Julia telle que: \n", + "- $u_0 = z$\n", + "- $u_{n+1} = u_n ^2 + c$ \n", + "\n", + "Dans laquelle $~z~$ et $~c~$ sont des nombres complexes : $~~z = a + bi~~$ et $~~c = p + qi$ , avec : \n", + "- $~z~\\Rightarrow$ qui représente la valeur initiale de la suite $u_0$ ;\n", + "- $~c~\\Rightarrow$ un paramètre (sous forme *complexe*) de la suite de Julia.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u0 = 0.0 + 0.0 i\n", + "(-0.5+0.6j)\n", + "(-0.61+0j)\n", + "(-0.1279+0.6j)\n", + "(-0.84364159+0.44652j)\n", + "(0.012351021977728305-0.1534056855336j)\n", + "(-0.5233807566101395+0.596210566012932j)\n", + "(-0.5815396226356586-0.024090274277615786j)\n", + "(-0.1623920086195465+0.6280188980251884j)\n", + "(-0.8680365718132812+0.396029499397311j)\n", + "(0.09664812561246894-0.08753617798754354j)\n", + "(-0.49832172227226335+0.5830795849484489j)\n", + "(-0.5916572634952607+0.018877554013384867j)\n", + "(-0.1502980445988279+0.5776619161019134j)\n", + "(-0.8111037871043028+0.42635708714134046j)\n", + "(-0.02389101230070656-0.091639696078201j)\n", + "(-0.5078270534285525+0.6043787302124746j)\n", + "(-0.6073853333393171-0.013839739437382148j)\n", + "(-0.13127459523198132+0.6168121095030072j)\n", + "(-0.8632241590762293+0.43805647998161634j)\n", + "(0.05326246915897892-0.1562818731200477j)\n" + ] + } + ], + "source": [ + "def suiteJulia(z: complex, c: complex) -> complex :\n", + " \"\"\"\n", + " Calcul de la suite de Julia: \n", + " En entrée: z et c sont des complexes.\n", + " Retourne un complexe.\n", + " \"\"\"\n", + " u = z\n", + " print(f'u0 = {(u.real)} + {(u.imag)} i')\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " print(u)\n", + "\n", + "z = complex(0, 0)\n", + "suiteJulia(z, complex(-0.5, 0.6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

6/ Analyse et exploitation des résultats :

\n", + "

61/ Mise en place des points dans le plan complexe : => avec Geogebra :

\n", + "\n", + "Examiner les valeurs obtenues en retour à l’exécution du code précédent. \n", + "Utiliser le logiciel ```Géogebra``` pour placer directement dans le *plan complexe*, les points obtenus : => tester tout d'abord pour un point, saisie en mode tableur et sans oublier de cocher \"Afficher l'objet\". \n", + "***Remarque*** : *Le mode tableur de ```Géogebra``` accepte de charger des points à partir d'un fichier, .dat par exemple (clic droit).* \n", + "**Cependant cette fonctionnalité dépend de la version de ```Géogebra``` à votre disposition:** *si votre version ne propose pas cette fonctionnalité, vous pouvez réaliser cette partie avec : Matplotlib*. \n", + "**Remarque** : Matplolib est moins adapté, puisqu'il vous faudra vous même mettre en place les points dans le plan complexe, à l'aide de leur partie réelle et partie imaginaire. \n", + "\n", + "Afin de pouvoir charger les points à partir d'un fichier, il faut adapter le code ci-dessus afin d'enregistrer les points dans un fichier ```Julia.dat``` et transformer le type ```complex``` de Python pour l'adapter au type reconnu par ```Géogebra``` : \n", + "$~a+bj \\Rightarrow a+bi~$. \n", + "A voir : l'exercice sur le tracé d'une spirale dans les activités de révision et aussi [ici](https://python.doctor/page-lire-ecrire-creer-fichier-python \"python.doctor: lire ecrire dans un fichier\")." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0j" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\" Saisir ici le code précédent, adapté pour générer un fichier : Julia.dat => et l'importer dans Géogebra \"\n", + "\n", + "def suiteJuliaFichier(z: complex, c: complex) -> complex :\n", + " \"\"\"\n", + " Calcul de la suite de Julia: \n", + " En entrée: z et c sont des complexes.\n", + " Retourne un complexe.\n", + " \"\"\"\n", + " with open('Julia.dat', 'w') as file:\n", + " u = z\n", + " print(f'u_0 = {(u.real)} + {(u.imag)} i', file=file)\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " print(f'u_{i+1} = {(u.real)} + {(u.imag)} i', file=file)\n", + " return z\n", + "z = complex(0, 0)\n", + "suiteJuliaFichier(z, complex(-0.5, 0.6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

=> avec Matplotlib :

\n", + "\n", + "Pour représenter les points avec Matplotlib, il vous faut extraire la partie réel et la partie imaginaire des résultats renvoyé par la fonction ```suiteJulia()```. \n", + "**=> Compléter le code suivant :**" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u0 = 0.0 + 0.0 i\n" + ] + }, + { + "data": { + "image/png": "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oqqqKvr27RtHHnlkzJ49OzZs2BA///nPIyLixz/+cZSXl8enP/3p2LFjR9x2223xyCOPxH//93/nc5oAAAAtlteIevbZZ+Pkk09uuD9r1qyIiLjgggtiwYIFUV1dHevXr294fOfOnXHFFVfEhg0bolevXvGZz3wmHn744UbPAQAA0J4KsizL2nsSram2tjZKSkoil8tFcXFxe08HAABoJ/lqg4N+YQkAAICDiYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIkNeIevzxx2Py5MkxcODAKCgoiAceeGC/+yxdujRGjRoVhYWFceyxx8aCBQvyOUUAAIAkeY2o7du3x/Dhw+Omm25q0fh169bFGWecESeffHJUVVXF5ZdfHl/72tfi97//fT6nCQAA0GKH5PPJTzvttDjttNNaPH7+/PlRXl4e119/fUREfOpTn4onnngibrjhhpg4cWK+pgkAANBiB9V7oiorK2PChAmNtk2cODEqKyv3uU9dXV3U1tY2ugEAAOTLQRVRNTU1MWDAgEbbBgwYELW1tfHuu+82uc+8efOipKSk4TZo0KC2mCoAANBFHVQR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xBFHHBHDhg2L2bNnxzvvvJOvaQIAACTJ25mompqa6N+/f+MXO+SQ6Nu3b9TU1Oxzvy9/+ctx1FFHxcCBA+P555+P7373u7FmzZq47777mhxfV1cXdXV1Dfdra2tb5wsAAABoQnJEXXnllXHNNdc0O+all1464AldfPHFDf/7uOOOi7KysjjllFPilVdeiWOOOWav8fPmzYu5c+ce8OsBAACkSI6oK664Ii688MJmxxx99NFRWloamzZtarT9L3/5S2zevDnp/U5jx46NiIi1a9c2GVGzZ8+OWbNmNdyvra2NQYMGtfj5AQAAUiRHVL9+/aJfv377HVdRURFbtmyJFStWxOjRoyMi4pFHHon6+vqGMGqJqqqqiIgoKytr8vHCwsIoLCxs8fMBAAB8GHlbWOJTn/pUTJo0KaZPnx7Lly+PJ598Mi699NI499xzG1bm27BhQwwZMiSWL18eERGvvPJKfP/7348VK1bEq6++Gr/5zW9i6tSpceKJJ8ZnPvOZfE0VAACgxfL6Ybu/+MUvYsiQIXHKKafE6aefHp///Ofj1ltvbXh8165dsWbNmobV93r27BkPP/xwnHrqqTFkyJC44oor4qyzzoqFCxfmc5oAAAAtVpBlWdbek2hNtbW1UVJSErlcLoqLi9t7OgAAQDvJVxvk9UwUAABAZyOiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASJC3iPrBD34Q48aNi169ekWfPn1atE+WZXH11VdHWVlZHHrooTFhwoT4wx/+kK8pAgAAJMtbRO3cuTPOPvvsmDFjRov3ufbaa+MnP/lJzJ8/P5YtWxYf+chHYuLEibFjx458TRMAACBJQZZlWT5fYMGCBXH55ZfHli1bmh2XZVkMHDgwrrjiivjWt74VERG5XC4GDBgQCxYsiHPPPbdFr1dbWxslJSWRy+WiuLj4w04fAADooPLVBgfNe6LWrVsXNTU1MWHChIZtJSUlMXbs2KisrGzHmQEAAPzVIe09gT1qamoiImLAgAGNtg8YMKDhsabU1dVFXV1dw/3a2tr8TBAAACASz0RdeeWVUVBQ0Ozt5ZdfztdcmzRv3rwoKSlpuA0aNKhNXx8AAOhaks5EXXHFFXHhhRc2O+boo48+oImUlpZGRMTGjRujrKysYfvGjRtjxIgR+9xv9uzZMWvWrIb7tbW1QgoAAMibpIjq169f9OvXLy8TKS8vj9LS0liyZElDNNXW1sayZcuaXeGvsLAwCgsL8zInAACAD8rbwhLr16+PqqqqWL9+fezevTuqqqqiqqoqtm3b1jBmyJAhcf/990dEREFBQVx++eXxL//yL/Gb3/wmXnjhhZg6dWoMHDgwpkyZkq9pAgAAJMnbwhJXX3113HnnnQ33R44cGRERjz76aIwfPz4iItasWRO5XK5hzHe+853Yvn17XHzxxbFly5b4/Oc/H4sWLYqioqJ8TRMAACBJ3j8nqq35nCgAACCiC3xOFAAAQEcgogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABLkLaJ+8IMfxLhx46JXr17Rp0+fFu1z4YUXRkFBQaPbpEmT8jVFAACAZIfk64l37twZZ599dlRUVMS///u/t3i/SZMmxR133NFwv7CwMB/TAwAAOCB5i6i5c+dGRMSCBQuS9issLIzS0tI8zAgAAODDO+jeE7V06dLo379/DB48OGbMmBFvv/12s+Pr6uqitra20Q0AACBfDqqImjRpUvz85z+PJUuWxDXXXBOPPfZYnHbaabF79+597jNv3rwoKSlpuA0aNKgNZwwAAHQ1SRF15ZVX7rXwwwdvL7/88gFP5txzz40vfvGLcdxxx8WUKVPioYceimeeeSaWLl26z31mz54duVyu4fb6668f8OsDAADsT9J7oq644oq48MILmx1z9NFHf5j57PVcRxxxRKxduzZOOeWUJscUFhZafAIAAGgzSRHVr1+/6NevX77mspc33ngj3n777SgrK2uz1wQAAGhO3t4TtX79+qiqqor169fH7t27o6qqKqqqqmLbtm0NY4YMGRL3339/RERs27Ytvv3tb8fTTz8dr776aixZsiTOPPPMOPbYY2PixIn5miYAAECSvC1xfvXVV8edd97ZcH/kyJEREfHoo4/G+PHjIyJizZo1kcvlIiKie/fu8fzzz8edd94ZW7ZsiYEDB8app54a3//+912uBwAAHDQKsizL2nsSram2tjZKSkoil8tFcXFxe08HAABoJ/lqg4NqiXMAAICDnYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABIIKIAAAASiCgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAgQd4i6tVXX41p06ZFeXl5HHrooXHMMcfEnDlzYufOnc3ut2PHjpg5c2Ycfvjhcdhhh8VZZ50VGzduzNc0AQAAkuQtol5++eWor6+PW265JV588cW44YYbYv78+XHVVVc1u983v/nNWLhwYdx7773x2GOPxZtvvhlf+tKX8jVNAACAJAVZlmVt9WI//OEP4+abb44//vGPTT6ey+WiX79+cffdd8ff//3fR8R7MfapT30qKisr44QTTtjva9TW1kZJSUnkcrkoLi5u1fkDAAAdR77a4JBWe6YWyOVy0bdv330+vmLFiti1a1dMmDChYduQIUPiyCOP3GdE1dXVRV1dXaPXiHjvGwYAAHRde5qgtc8btVlErV27Nm688ca47rrr9jmmpqYmevbsGX369Gm0fcCAAVFTU9PkPvPmzYu5c+futX3QoEEfar4AAEDn8Pbbb0dJSUmrPV9yRF155ZVxzTXXNDvmpZdeiiFDhjTc37BhQ0yaNCnOPvvsmD59evosmzF79uyYNWtWw/0tW7bEUUcdFevXr2/VbxQtV1tbG4MGDYrXX3/dJZXtxDFof45B+3MM2p9j0P4cg/bl+9/+crlcHHnkkc1eDXcgkiPqiiuuiAsvvLDZMUcffXTD/37zzTfj5JNPjnHjxsWtt97a7H6lpaWx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nom68sorm3zj3ftvH/xHesOGDTFp0qQ4++yzY/r06e00887jQI5BinPPPTe++MUvxnHHHRdTpkyJhx56KJ555plYunRp630RHVy+jwH7l+9jcPHFF8fEiRPjuOOOi/PPPz9+/vOfx/333x+vvPJKK34VcHCoqKiIqVOnxogRI+Kkk06K++67L/r16xe33HJLe08N2sTgwYPj61//eowePTrGjRsXt99+e4wbNy5uuOGG9p5ahzdz5sxYtWpV/OpXv2qT1ztoz0RdccUVceGFFzY75uijj27432+++WacfPLJMW7cuLj11lub3a+0tDR27twZW7ZsaXQ2auPGjVFaWvphpt2ppB6DD+voo4+OI444ItauXRunnHJKqz1vR5bPY7DnZ33jxo1RVlbWsH3jxo0xYsSIA3rOzqilx6C0tHSvN9P/5S9/ic2bNyf9uzJ27NiIeO+s+jHHHJM8367iiCOOiO7du++1qmpz/46XlpYmjad5B3IMPqhHjx4xcuTIWLt2bT6myAfs63eguLjYWah2NGbMmHjiiSfaexod2qWXXtqwoNP+zmq31t+Cgzai+vXrF/369WvR2A0bNsTJJ58co0ePjjvuuCO6dWv+BNvo0aOjR48esWTJkjjrrLMi4r1VUtavXx8VFRUfeu6dRcoxaA1vvPFGvP32243+g76ry+cxKC8vj9LS0liyZElDNNXW1sayZcuSV1nszFp6DCoqKmLLli2xYsWKGD16dEREPPLII1FfX98QRi1RVVUVEeH3YD969uwZo0ePjiVLlsSUKVMi4r1LOZYsWRKXXnppk/tUVFTEkiVL4vLLL2/YtnjxYv/uH6ADOQYftHv37njhhRfi9NNPz+NM2aOiomKvpZz9DrS/qqoq/+YfoCzL4hvf+Ebcf//9sXTp0igvL9/vPq32t+BAVr44mLzxxhvZsccem51yyinZG2+8kVVXVzfc3j9m8ODB2bJlyxq2XXLJJdmRRx6ZPfLII9mzzz6bVVRUZBUVFe3xJXQKr732Wvbcc89lc+fOzQ477LDsueeey5577rls69atDWMGDx6c3XfffVmWZdnWrVuzb33rW1llZWW2bt267OGHH85GjRqVffKTn8x27NjRXl9Gh5Z6DLIsy/71X/8169OnT/bggw9mzz//fHbmmWdm5eXl2bvvvtseX0KHN2nSpGzkyJHZsmXLsieeeCL75Cc/mZ133nkNj3/w36K1a9dm3/ve97Jnn302W7duXfbggw9mRx99dHbiiSe215fQofzqV7/KCgsLswULFmSrV6/OLr744qxPnz5ZTU1NlmVZ9tWvfjW78sorG8Y/+eST2SGHHJJdd9112UsvvZTNmTMn69GjR/bCCy+015fQ4aUeg7lz52a///3vs1deeSVbsWJFdu6552ZFRUXZiy++2F5fQoe2devWhn/rIyL70Y9+lD333HPZa6+9lmVZll155ZXZV7/61Ybxf/zjH7NevXpl3/72t7OXXnopu+mmm7Lu3btnixYtaq8vocNLPQY33HBD9sADD2R/+MMfshdeeCG77LLLsm7dumUPP/xwe30JHdqMGTOykpKSbOnSpY0a4J133mkYk6+/BR0+ou64444sIpq87bFu3bosIrJHH320Ydu7776b/eM//mP20Y9+NOvVq1f2d3/3d43CizQXXHBBk8fg/d/ziMjuuOOOLMuy7J133slOPfXUrF+/flmPHj2yo446Kps+fXrDH17SpR6DLHtvmfN/+qd/ygYMGJAVFhZmp5xySrZmzZq2n3wn8fbbb2fnnXdedthhh2XFxcXZRRdd1ChiP/hv0fr167MTTzwx69u3b1ZYWJgde+yx2be//e0sl8u101fQ8dx4443ZkUcemfXs2TMbM2ZM9vTTTzc8dtJJJ2UXXHBBo/G//vWvs7/5m7/JevbsmX3605/Ofvvb37bxjDuflGNw+eWXN4wdMGBAdvrpp2crV65sh1l3DnuWy/7gbc/3/IILLshOOumkvfYZMWJE1rNnz+zoo49u9DeBdKnH4JprrsmOOeaYrKioKOvbt282fvz47JFHHmmfyXcC+2qA9/9c5+tvQcH/TgAAAIAWOGhX5wMAADgYiSgAAIAEIgoAACCBiAIAAEggogAAABKIKAAAgAQiCgAAIIGIAgAASCCiAAAAEogoAACABCIKAAAggYgCAABI8P8DHNixtVLaByAAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\"Représentation des point dans le plan complexe, avec Matplotlib :\"\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "def suiteJulia(u: complex, c: complex) -> 'list[complex]' :\n", + " \"\"\"\n", + " Calcul de la suite de Julia: \n", + " En entrée: z et c sont des complexes.\n", + " Retourne une liste de complexes.\n", + " \"\"\"\n", + " u = z\n", + " s = [u]\n", + " print(f'u0 = {(u.real)} + {(u.imag)} i')\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " s.append(u)\n", + " return s\n", + "\n", + "def tracer_les_points(listePoints):\n", + " \"Pour tracer les points :\"\n", + " plt.figure(figsize=(10,10))\n", + " plt.xlim([-2, 2])\n", + " plt.ylim([-2, 2])\n", + " plt.scatter([z.real for z in listePoints], [z.imag for z in listePoints])\n", + " plt.show()\n", + " plt.close()\n", + "\n", + "u = complex(0, 0)\n", + "tracer_les_points(suiteJulia(u, complex(-0.5, 0.6)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

62/ Le point d'affixe z = 0 + 0i appartient-il à l'ensemble de Julia J(c) ?

\n", + "

=> avec Geogebra :

\n", + "\n", + "Pour le savoir : tracer dans ```géogebra``` un cercle de centre 0 et de rayon 2. Si les points de la suite sont dans ce cercle, c'est donc que le point z appartient à l'ensemble de Julia (du moins en ce qui concerne les vingts premiers termes de la suite). \n", + "\n", + "Essayer maintenant la suite, pour laquelle: $~z = 0.239 + 0.2i~$ et $~c = -0.5 + 0.6i$ \n", + "Cette fois vous devriez constater que les dernières valeurs de la suite \"s'échappent\" du cercle. \n", + "$\\Rightarrow$ On en déduit que le point M d'affixe $~z = 0.239 + 0.2i~$ n'appartient pas à l'ensemble J(c). \n", + "\n", + "

=> avec Matplotlib :

\n", + "\n", + "Reprendre les étapes décrites ci-dessus en les adaptant à Matplotlib **=> compléter le code ci-dessous:**" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u0 = 0.0 + 0.0 i\n", + "u0 = 0.0 + 0.0 i\n" + ] + }, + { + "data": { + "image/png": "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rPr06aPKlStr37592rhxo1q1aqUMGTKYjggAaSZnzpzq16+fjh49qsWLFys6Olr16tVTYGCgFi9erISEBNMRAaQxShSANBMREaEBAwYoX758+uSTT9SqVSsdO3ZM8+fPV5kyZUzHAwCbcnd31yuvvKLdu3dr/fr1yp49u1577TUVL15c3377re7cuWM6IoA0QokC8MROnDiht956S/nz59fUqVPVq1cvnTp1SlOnTlXBggVNxwOAdGWxWFSnTh1t2LBBO3fu1AsvvKA333xTBQoU0H//+19dv37ddEQAT4gSBSDV9u3bp9atW6to0aJatmyZhg8frrNnz2rMmDHy9/c3HQ8AjKtYsaKWLFmiw4cPq2HDhho8eLDy5cunDz/8UJcvXzYdD0AqUaIApIjValVoaKgaNGigcuXKaffu3Zo8ebJOnz6tgQMHKlu2bKYjAoDdKVasmGbMmKGTJ0+qS5cumjhxYtK60dOnT5uOByCFKFEAkiUxMVHLli1TlSpVVLNmTUVERGjevHk6duyYevToIR8fH9MRAcDuPfPMMxo/frzOnDmjgQMHav78+SpUqJA6duyo8PBw0/EAJBMlCsAjJSQkaM6cOSpZsqRatGghLy8vrV69Wvv371fbtm3l4eFhOiIAOJycOXNq6NChOnPmjCZMmKDNmzfrhRdeUFBQkHbt2mU6HoDHoEQBeCCr1aply5apVKlS6tSpkwoWLKitW7dq8+bNatiwoSwWi+mIAODwMmXKpP/85z/6/fffNXv2bJ04cUKVKlVSy5YtdfjwYdPxADwEJQrAv2zatElVqlRRixYt9PTTT2v37t1asWKFqlatajoaADilDBkyqFOnTjp48KDmzJmjffv26YUXXtAbb7yhM2fOmI4H4B8oUQCS7NmzR/Xr11etWrWUmJioDRs2aN26dQoMDDQdDQBcgru7uzp06KDffvtNkyZN0urVq1WkSBG9++677OYH2BFKFAAdPXpUr732mgIDA3X27FktWbJEO3fuVO3atU1HAwCX5OXlpbffflu///67PvroI3333Xd67rnnNGzYMMXExJiOB7g8ShTgws6fP68333xTzz//vHbs2KHvvvtOBw8eVMuWLVnzBAB2IHPmzPrwww918uRJ9ejRQ2PGjFHBggU1ceJExcbGmo4HuCxKFOCC/vjjD73//vsqVKiQli5dqnHjxunYsWN644032G0PAOxQzpw5NW7cOJ04cUItWrRQ//79VaRIEc2cOVPx8fGm4wEuhxIFuJAbN27o008/1XPPPadp06Zp4MCB+v333/Xuu+/K29vbdDwAwGM888wz+vrrr3Xo0CFVrlxZXbp0UalSpfTjjz/KarWajge4DEoU4ALi4uL01VdfqWDBghoxYoS6dOmikydPatiwYcqaNavpeACAFCpatKgWLVqk3bt365lnnlGrVq1UuXJl/fTTT6ajAS6BEgU4MavVqgULFqho0aJ655131KhRIx07dkyff/65cuXKZToeAOAJBQYGat26ddq4caMkqXbt2qpbt64OHDhgOBng3ChRgJM6ePCgatSoobZt26p06dI6ePCgZs6cqWeffdZ0NABAGqtVq5Z27NihH3/8UefOnVPZsmX1n//8R9euXTMdDXBKlCjAyVy7dk19+/ZV2bJlFRUVpbVr12rZsmUqUaKE6WgAABuyWCxq0aKFDhw4oM8++0wzZ85M2nwiMTHRdDzAqVCiACeRmJioWbNmqWjRovr22281evRoHThwQPXq1TMdDQCQjjw9PdW/f3/99ttvqlu3rrp06aKqVasqLCzMdDTAaVCiACewZ88evfjii3rjjTdUu3ZtHT16VO+//748PT1NRwMAGPL0009r7ty52rx5s27duqWKFSvqrbfe0pUrV0xHAxweJQpwYH/88Yd69OihChUq6MaNGwoNDdW8efP09NNPm44GALATL7/8svbu3atJkyZp4cKFKlq0qKZNm6aEhATT0QCHRYkCHFBCQoKmT5+uIkWKaP78+Zo4caL27dun6tWrm44GALBDHh4e6tOnj44dO6ZmzZqpZ8+eqlChgrZv3246GuCQKFGAg9m+fbsqVqyoHj16KCgoSMeOHdN//vMfeXh4mI4GALBzuXPn1nfffaft27fLYrGoatWq6ty5s6KiokxHAxwKJQpwEFFRUXrjjTdUtWpVSdK2bds0c+ZM5cmTx3AyAICjqVy5snbt2qXp06drxYoVKlKkiCZOnKi7d++ajgY4BEoUYOfi4+M1adIkFSlSRCEhIZo2bZp27dqlKlWqmI4GAHBg7u7uevPNN3Xs2DG1a9dO7733nsqVK6fQ0FDT0QC7R4kC7NiePXtUvnx5vfvuu2rbtq2OHTumt956S+7u7qajAQCcRM6cOTV16lSF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50i1vn376pdfftGGDRtUoEAB03EAAADsXvv27XXw4EF98MEHKlGihBo2bGg6ElKBkSikyrRp0zRlyhRNnjxZ1atXNx0HAADAYYwcOVKNGjVSmzZtdOTIEdNxkAqUKKRYaGio+vTpo7fffltvvvmm6TgAAAAOxd3dXXPnzlXevHkVFBSkq1evmo6EFKJEIUVOnjypVq1aqXr16vr8889NxwEAAHBIWbNmVUhIiK5evarWrVsrPj7edCSkACUKyRYTE6OgoCDlyJFDixYtkocHS+oAAABS67nnntMPP/yg0NBQvffee6bjIAUoUUiWhIQEtW/fXufOndOKFSuUI0cO05EAAAAcXs2aNfXll1/qyy+/1DfffGM6DpKJoQQky5AhQ7R69WqtXLlSxYoVMx0HAADAafTo0UMHDx5Ur169VLRoUb388sumI+ExGInCYwUHB+uzzz7T2LFj2YYTAADABiZOnKiXXnpJrVq10unTp03HwWNQovBIO3fuVLdu3dS5c2fm6gIAANhIhgwZtHjxYvn6+iooKEjXr183HQmPQInCQ124cEEtWrRQuXLlNG3aNFksFtORAAAAnFbOnDkVEhKi06dPq2PHjkpMTDQdCQ9BicID3b59W82bN5eHh4d+/PFHeXl5mY4EAADg9EqUKKH58+crJCREQ4cONR0HD0GJwr9YrVb16NFDhw8f1vLly+Xn52c6EgAAgMto3LixPvvsM40cOVJLliwxHQcPQInCv8yaNUvff/+9pk+frrJly5qOAwAA4HL69++vV199VV27dtXJkydNx8E/WKxWq9V0iLQUExMjX19fRUdHK2vWrKbjOJzDhw8rMDBQbdu21YwZM0zHAQAAcFnR0dEqV66ccubMqS1btsjT09N0JIdjq27ASBSS3Lp1S6+99pqee+45ffnll6bjAAAAuDRfX18tXLhQ+/fv18CBA03Hwd9QopCkT58+OnnypBYtWqSMGTOajgMAAODyAgMD9d///leff/65QkJCTMfB/6FEQdJfB+p+9913mjx5skqUKGE6DgAAAP5Pnz591Lx5c3Xu3Flnz541HQeiREHS0aNH1aNHD3Xs2FGdO3c2HQcAAAB/Y7FY9N133ylr1qxq06aN7t69azqSy6NEubjbt2/rtddeU968eTVlyhQO1AUAALBD2bNn18KFC7V79259+OGHpuO4PEqU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qqh58+b66KOPdOfOHdNxjKBEGWC1WjVw4ECVLFlSHTp0MB0HAAAASJFRo0bp7NmzmjZtmukoRlCiDPj555+1adMmjRo1Su7u7qbjAAAAAClSvHhxde7cWaNGjdLt27dNx0l3lCgDRo0apdKlS6tJkyamowAAAACpMmjQIF25ckUzZ840HSXdUaLSWVhYmNatW6fBgwfLYrGYjgMAAACkSqFChdS6dWuNHTtWd+/eNR0nXVGi0tno0aNVuHBhtWrVynQUAAAA4IkMHDhQZ86c0fz5801HSVeUqHR05MgR/fjjjxowYABroQAAAODwSpUqpSZNmmjMmDEudW4UJSodffbZZ3rmmWfUsWNH01EAAACANDF48GAdOXJEy5cvNx0l3VCi0snp06cVHBysfv36ydPT03QcAAAAIE1UqVJFNWrU0KhRo2S1Wk3HSReUqHTy3//+V9myZVP37t1NRwEAAADS1ODBgxUWFqYNGzaYjpIuKFHpICoqSjNmzFDfvn2VKVMm03EAAACANFWnTh2VL19eo0aNMh0lXVCi0sHEiROVIUMG9e7d23QUAAAAIM1ZLBYNHjxYoaGh2r59u+k4NkeJsrFr165p8uTJ6tmzp7Jnz246DgAAAGATzZs3V7FixTR69GjTUWyOEmVjkydPVlxcnN59913TUQAAAACbcXNz06BBg7RixQodOHDAdBybokTZ0M2bNzVx4kR17dpVfn5+puMAAAAANtW2bVs9++yzGjNmjOkoNkWJsqFvv/1Wf/75p95//33TUQAAAACby5Ahg95//30tXLhQJ06cMB3HZihRNhIXF6f//ve/ateunfLnz286DgAAAJAuunTpoqeeekrjxo0zHcVmKFE2EhwcrPPnz2vgwIGmowAAAADpxsfHR++9955mzZqlCxcumI5jE5QoG0hISNCYMWPUokULlShRwnQcAAAAIF317NlTPj4+mjBhgukoNkGJsoGVK1fq+PHjjEIBAADAJWXNmlW9e/fW119/rZiYGNNx0hwlygamTJmiihUrqmLFiqajAAAAAEb07NlTt2/fVnBwsOkoaY4SlcaOHTumdevWqXfv3qajAAAAAMY888wzatasmSZPniyr1Wo6TpqiRKWxqVOnKmfOnHrttddMRwEAAACM6tWrlw4fPqzNmzebjpKmKFFp6ObNm5o5c6a6du0qb29v03EA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VqstbzBr1iz17dtX165de+R1VqtVAQEB6tevX9IpyNHR0cqTJ49mzZqlNm3aJOt+MTEx8vX1VXR0tEMfBBYbG6uSJUsqf/78Wr9+PUOoAAAASBcXL15UsWLF1KlTJ3311Vem4zwRW3UDu1kTderUKUVGRqpOnTpJz/n6+qpSpUravn27wWRmeHt768svv9TGjRu1ePFi03EAAADgIvr37y9vb299+umnpqPYLbspUZGRkZKkPHny3Pd8njx5kl57kDt37igmJua+h7No2LChmjdvrnfffVfXr183HQcAAABObtOmTZo/f77GjRuX7H0NXFGKStTAgQNlsVge+fjtt99slfWBRo8eLV9f36RH3rx50/X+tvb555/rzz//1IgRI0xHAQAAgBO7e/euevfurRdffFEdO3Y0HceueaTk4n79+qlz586PvOa5555LVRA/Pz9JUlRUlPz9/ZOej4qKUpkyZR76vkGDBum9995L+n1MTIxTFan8+fNryJAhGjZsmDp37qwSJUqYjgQAAAAnNGnSJB09elR79+7lYN3HSFGJypUrl3LlymWTIAUKFJCfn582btyYVJpiYmK0c+fOR+7w5+XlJS8vL5tkshf9+/fX7Nmz1bt3b/30009sMgEAAIA0df78eQ0bNkxvv/22SpcubTqO3bNZxTx79qz279+vs2fPKiEhQfv379f+/ft148aNpGuKFSumpUuXSpIsFov69u2rTz/9VCEhITp48KA6deqkgIAANW/e3FYxHYKXl5e+/PJLhYaGasGCBabjAAAAwMn0799fmTNn1ieffGI6ikNI0UhUSgwdOlSzZ89O+n3ZsmUl/bVYrUaNGpKko0ePKjo6OumaDz74QDdv3tSbb76pa9euqVq1alqzZo28vb1tFdNh1K9fX61atVK/fv3UuHFjh96+HQAAAPZj48aNWrhwoebMmSNfX1/TcRyCzc+JSm/Ock7Ug5w9e1bFixdXjx49NH78eNNxAAAA4ODi4uJUunRp5cqVS5s3b3a6ZSNOf04UHi9fvnz66KOPNGnSJIWHh5uOAwAAAAf3+eef6/jx45o8ebLTFShbYiTKwcTFxalUqVLKkyePQkND+cMOAACAVDl37pyKFSumt956SxMmTDAdxyYYiYIkydPTU1999ZV+/vlnzZ0713QcAAAAOKj33ntPWbNm1bBhw0xHcTiU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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\"Savoir si un point z appartient à l'ensemble de Julia J(c) :\"\n", + "\n", + "import matplotlib.pyplot as plt\n", + "\n", + "def suiteJulia(u: complex, c: complex) -> 'list[complex]' :\n", + " \"\"\"\n", + " Calcul de la suite de Julia: \n", + " En entrée: z et c sont des complexes.\n", + " Retourne une liste de complexes.\n", + " \"\"\"\n", + " u = z\n", + " s = [u]\n", + " print(f'u0 = {(u.real)} + {(u.imag)} i')\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " s.append(u)\n", + " return s\n", + "\n", + "def tracer_les_points(listePoints):\n", + " \"Pour tracer les points :\"\n", + " plt.figure(figsize=(10,10))\n", + " plt.xlim([-2, 2])\n", + " plt.ylim([-2, 2])\n", + " plt.scatter([z.real for z in listePoints], [z.imag for z in listePoints])\n", + " cercle = plt.Circle((0, 0), 2,fill=False)\n", + " plt.gcf().gca().add_artist(cercle)\n", + " plt.show()\n", + " plt.close()\n", + "\"\"\"\n", + "def cercle_limite():\n", + " cercle = plt.Circle((0, 0), 2,fill=False)\n", + " plt.gcf().gca().add_artist(cercle) #gca = Get Current Axis\n", + " plt.show()\n", + " plt.close()\n", + "\"\"\"\n", + "u = complex(0, 0)\n", + "suiteJulia(u, complex(-0.5, 0.6))\n", + "tracer_les_points(suiteJulia(u, complex(-0.5, 0.6)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

63/ Savoir si un point appartient à l'ensemble de Julia :

\n", + "\n", + "Pour savoir si un point $M$ d'affixe $z$ appartient à l'ensemble de Julia J(c), on peut se limiter à examiner ***le module $u_n$*** de la suite de Julia : \n", + "D'après la définition du module d'un nombre complexe (distance du point $M$ d'affixe $z = a + jb$, à l'origine $O$ du plan complexe), regarder si un point de la suite \"s'échappe\" du domaine de Julia, limité par le cercle de centre $0$ et de rayon 2, revient à examiner si **le module du complexe $~u_n~$ calculé est supérieur à 2**. \n", + "On peut d'ailleurs démontrer que la suite tend vers l'infini (n'appartient donc pas à J(c)) lorsque justement ses termes $u_n$ sortent du cercle de rayon 2, centré en $O$. \n", + "\n", + "Appliquer cette propriété pour examiner et conclure sur l'évolution de $|u_n|$ pour les valeurs de $~z~$ et du paramètre $~c~$ suivantes :" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "u0 = 0.0 + 0.0 i\n", + "0.7810249675906654\n", + "0.61\n", + "0.6134805701894722\n", + "0.9545214731883868\n", + "0.15390208607399739\n", + "0.7933438443797638\n", + "0.5820383784682888\n", + "0.6486747264540702\n", + "0.9541105042909015\n", + "0.13039724936159686\n", + "0.7670113045268956\n", + "0.5919583427000827\n", + "0.5968942884001868\n", + "0.9163349383334626\n", + "0.0947027685237214\n", + "0.789406084171619\n", + "0.6075429874036964\n", + "0.6306268292602768\n", + "0.9680131344495009\n", + "0.16510879590991473\n" + ] + } + ], + "source": [ + "'''Modifier le code de la fonction suite de Julia afin d'afficher 20 itérations du module de u => abs(u)\n", + "Ceci pour les valeurs suivantes de la suite :\n", + "z = 0 + 0i et c = -0.5 + 0.6i\n", + "z = 0.239 + 0.2i et c = -0.5 + 0.6i\n", + "z = 0.25 + 0.2i et c = -0.5 + 0.6i\n", + "'''\n", + "\n", + "def suiteJulia(z: complex, c: complex) -> complex :\n", + " \"\"\"\n", + " Calcul de la suite de Julia: \n", + " En entrée: z et c sont des complexes.\n", + " Retourne un complexe.\n", + " \"\"\"\n", + " u = z\n", + " print(f'u0 = {(u.real)} + {(u.imag)} i')\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " print(abs(u))\n", + "\n", + "z = complex(0, 0)\n", + "suiteJulia(z, complex(-0.5, 0.6))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

7/ Construction des fractales de Julia :

\n", + "

71/ Calculer l'ensemble de Julia :

\n", + "\n", + "**Écrire une fonction ```ensembleJulia```** qui devra itérer 100 fois (ou plus) le calcul de la suite de Julia à partir du point $~M~$ d'affixe $~z~$ et du paramètre $~c~$. \n", + "Cette fonction doit renvoyer : \n", + "- -1 si le point $M$ appartient à J(c) => dans ce cas toutes les itérations donnent un module inférieur à 2;\n", + "- l'indice i du tour de boucle qui correspond au premier terme de la suite supérieur à 2. " + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "def ensembleJulia (z: complex, c: complex) -> int :\n", + " '''Prend une suite de Julia et un point d'affixe z :\n", + " Retourne => -1 si le point est dans l'ensemble J(c): le module de tous les termes est < 2\n", + " Retourne l'indice i du premier terme ayant un module supérieur à 2\n", + " '''\n", + "\n", + " u = z\n", + " print(f'u0 = {(u.real)} + {(u.imag)} i')\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " if abs(u) > 2:\n", + " return i\n", + " return -1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

72/ Changement de repère :

\n", + "\n", + "Puisqu'il s'agit de tracer une image à l'écran, nous allons faire en sorte que les points $M$ (de la suite de Julia) appartiennent à l'écran de l'ordinateur. Donc le plan complexe sera représenté par l'écran de l'ordinateur. \n", + "L'écran est constitué de pixels ayant $x$ et $y$ pour coordonnées. Les dimensions de l'image de la fractale seront comprises entre 0 et 400 pixels pour $x$ et pour $y$. \n", + "Les ensembles de Julia intéressant sont pour $z = a + ib$ ayant une partie réelle $a$ et une partie imaginaire $b$ comprises entre -1.25 et +1.25. \n", + "Un changement de repère est donc nécessaire pour faire correspondre la partie du plan complexe pertinente (-1.25 -> +1.25) avec les pixels de notre image fractale (0 -> 400). \n", + "\n", + "![image](./images/ChgntRepere.png)\n", + "\n", + "\n", + "**Établir les équations** pour passer de l'image en pixel, à la valeur de $z$, et **écrire** la fonction ```convert``` correspondante :\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def convert(x:int, y:int) ->complex :\n", + " \"Convertit un point du plan (de l'image) de coordonnées x, y en un nombre complexe z = re + img*j\"\n", + " return complex(x/160 - 1.25, y/160 - 1.25)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

73/ Gestion des couleurs :

\n", + "\n", + "A chaque point de notre fractale correspond un affixe $z$ utilisé dans la fonction ```ensembleJulia``` pour savoir si ce point appartient ou pas à J(c). \n", + "Nous allons affecter une couleur à ce point, en fonction de sont appartenance ou pas à J(c). Dans ce dernier cas, sa couleur sera fonction du rang du terme pour lequel il s'échappe de J(c). \n", + "*Rappel: la couleur d'un pixel est définie par un triplet de nombres, chacun compris entre 0 et 255.* \n", + "Principe: si n représente le nombre renvoyé par la fonction ```ensembleJulia```:\n", + "- si n=-1 le pixel correspondant est noir.\n", + "- et pour 0< n <100 : \n", + "=> la couleur (n, n , n) donnera un dégradé allant de noir à gris moyen (100, 100, 100) \n", + "=> la couleur (2n, 0 , 0) donnera un dégradé allant de noir au rouge vif (200, 0, 0) \n", + "=> la couleur (0, 0, 3n%256) donnera un premier dégradé allant de noir au bleu vif (0, 0, 255), puis lorsque 3n dépasse 255 on reviend à zéro, jusqu'à atteindre la couleur (0, 0, 44) pour n=100. \n", + "\n", + "Pour commencer nous allons faire un \"mix\" de tout cela, soit par exemple : (4n%256, 2n, 6n%256). \n", + "Puis tester aussi la formule suivante: (255-log10(n)x127, 255-log10(n)x127, log10(n)x127). \n", + "Et pourquoi pas tester aussi une variante personnelle. \n", + "\n", + "**Écrire une fonction ```colorise```** permettant de fixer une couleur (d'après les formules ci-dessus) à chaque pixel d'un rectangle, en fonction d'une valeur de $n$, avec $-1 74/ Association des fonctions précédentes :\n", + "\n", + "Associer les fonctions précédentes pour obtenir le tracé des fractales de Julia. \n", + "La fonction ```dessineFractale``` est une évolution de la fonction ```colorise``` qui gère le tracé (position et couleur de chaque pixel) de la fractale de Julia, à l'aide des fonctions : ```convert``` et ```ensembleJulia```. \n", + "Tester les fractales pour les valeurs du paramètre $c$ successivement égal à : \n", + "- $-0.5+0.6i$\n", + "- $-0.8-0.18i$\n", + "- $0-0.8i$\n", + "- $0.285+0.013i$\n" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "from PIL import Image\n", + "from math import log10\n", + "\n", + "#***Déclaration des constantes :***\n", + "taille = 1000\n", + "reMax = -0.5\n", + "reMin = 0.5\n", + "imgMax = -0.5\n", + "imgMin = 0.5\n", + "\n", + "#***Déclaration des fonction locales :***\n", + "def ensembleJulia (z: complex, c: complex) -> int :\n", + " '''Prend une suite de Julia et un point d'affixe z :\n", + " Retourne => -1 si le point est dans l'ensemble J(c): le module de tous les termes est < 2\n", + " Retourne l'indice i du premier terme ayant un module supérieur à 2\n", + " '''\n", + " u = z\n", + " for i in range (20):\n", + " u = u **2 + c\n", + " if abs(u) > 2:\n", + " return i\n", + " return -1\n", + "\n", + "def convert(x:int, y:int, taille:int) ->complex :\n", + " \"Convertit un point du plan (de l'image) de coordonnées x, y en un nombre complexe z = re + img*j\"\n", + " return complex(x*(reMax-imgMin)/taille - (reMax-reMin)/2, y*(imgMax-imgMin)/taille - (imgMax-imgMin)/2)\n", + "\n", + "def dessineFractale(img, taille, c):\n", + " \"Construit la fractale à partir d'une carré de pixels à colorer en fonction de la valeur de n :\"\n", + " for x in range(taille):\n", + " for y in range(taille):\n", + " n = ensembleJulia(convert(x, y, taille), c)\n", + " if n == -1:\n", + " img.putpixel((x, y), (0,0,0))\n", + " else:\n", + " img.putpixel((x, y), (4*n%256, 2*n, 6*n%256))\n", + "\n", + "#*** Programme principal :***\n", + "\"Tester les fractales pour le paramètre c = -0.5+0.6j; -0.8-0.18j; 0-0.8j; 0.285+0.013j \"\n", + "img = Image.new('RGB',(taille,taille),(255,255,255))\n", + "dessineFractale(img, taille, 0-0.8j)\n", + "img.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

8/ Mise en évidence de la structure de la fractale :

\n", + "\n", + "Une figure fractale est un objet mathématique qui présente une structure similaire à toutes les échelles. \n", + "A partir d'une fractale de niveau 0, vérifier qu'il est possible d'obtenir une fractale de niveau 1, puis 2 et ainsi de suite : \n", + "=> Pour cela adapter les constantes du script (taille etc...) pour zoomer de plus en plus.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

9/ Ensemble de Mandelbrot :

\n", + "\n", + "Prolongement possible aux ensembles de Julia : $\\Rightarrow$ les ensembles de Mandelbrot. \n", + "A voir :\n", + "- https://fr.wikipedia.org/wiki/Ensemble_de_Mandelbrot\n", + "- le logiciel Xaos." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.10 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/102_Fractales/L-Systeme_EL-Valentin_Moguerou.ipynb b/102_Fractales/L-Systeme_EL-Valentin_Moguerou.ipynb new file mode 100644 index 0000000..37b0703 --- /dev/null +++ b/102_Fractales/L-Systeme_EL-Valentin_Moguerou.ipynb @@ -0,0 +1,491 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

  Tracer des fractales à l'aide du langage L-System :  

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Les L-systèmes sont une famille de grammaires formelles inventée par le biologiste `Aristid Lindenmayer` pour modéliser la croissance des plantes. Un L-système est constitué :\n", + "\n", + "- d'un axiome : la chaîne de caractère initiale ;\n", + "- d'un ensemble de règles de réécriture : chaque règle est de la forme : lettre → chaine.\n", + "\n", + "Le principe est de partir de l'axiome, et de remplacer dans la chaîne chaque lettre par la partie droite de la règle correspondante, si elle existe. Sinon, on laisse la lettre telle quelle. On répète cette opération plusieurs fois en fonction de l'ordre (ou du nombre de générations souhaités)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Exemple:

\n", + "\n", + "#### Soit le L-System suivant: \n", + "- variables: A, B \n", + "- Axiom: A \n", + "- Règles : \n", + " - A —> AB\n", + " - B —> A \n", + "\n", + "

Écrire à la main la suite des caractères obtenue avec ce L-system: à l'ordre 0 ; puis à l'ordre 1 et jusqu'à l'ordre 5.

" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Répondre ici:\n", + "- ordre 0 : => A\n", + "- ordre 1 : => AB\n", + "- ordre 2 : => ABA\n", + "- ordre 3 : => ABAAB\n", + "- ordre 4 : => ABAABA\n", + "- ordre 5 : => ABAABABAAB\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Codage du L-System :

" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 => A\n", + "1 => AB\n", + "2 => ABA\n", + "3 => ABAAB\n", + "4 => ABAABABA\n" + ] + } + ], + "source": [ + "def iterer_lSystem(chaine: str, k: int) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne initiale (l'axiome) et l'ordre k souhaité\n", + " Retourne la chaîne obtenue après k applications du L-system\n", + " \"\"\"\n", + " for _ in range(k):\n", + " chaine = lSystemConvert(chaine)\n", + " return chaine\n", + "\n", + "def lSystemConvert(chaine: str) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne de caractères\n", + " Retourne la chaîne obtenue après application des règles du L-System\n", + " \"\"\"\n", + " result = ''\n", + " for car in chaine:\n", + " if car == 'A': #règle 1 :\n", + " result += 'AB' # A -> AB\n", + " elif car == 'B': #règle 2 :\n", + " result += 'A' # B -> A\n", + " return result\n", + "\n", + "axiome = 'A'\n", + "for k in range (5):\n", + " print(f'{k} => {iterer_lSystem(axiome, k)}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Évolution :

\n", + "\n", + "Simplifier l'écriture de la fonction ```LSystemConvert()``` en utilisant d'une part un dictionnaire dont chacune des clés représente une règle du L-system et d'autre part une liste par compréhension pour remplacer l'itération sur ```chaine``` (le code : for car in chaine :)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 => A\n", + "1 => AB\n", + "2 => ABA\n", + "3 => ABAAB\n", + "4 => ABAABABA\n" + ] + } + ], + "source": [ + "def iter_lSystem(chaine: str, k: int) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne initiale (l'axiome) et l'ordre k souhaité\n", + " Retourne la chaîne obtenue après k applications du L-system\n", + " \"\"\"\n", + " for _ in range(k):\n", + " chaine = lSystemConvert(chaine)\n", + " return chaine\n", + "\n", + "def lSystemConvert(chaine: str) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne de caractères\n", + " Retourne la chaîne obtenue après application des règles du L-System\n", + " \"\"\"\n", + " rules = {\"A\":\"AB\",\"B\":\"A\"} # A compléter : règles\n", + " result = ''.join([rules[ch] for ch in chaine]) # A compléter : liste par compréhension et ''.join()\n", + " return result\n", + "\n", + "axiome = 'A'\n", + "for k in range (5):\n", + " print(f'{k} => {iter_lSystem(axiome, k)}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Flocon de Von Koch :

\n", + "\n", + "On souhaite définir et utiliser un L-System nous permettant d'obtenir une suite de caractères représentant les commandes à donner au module Turtle de Python pour tracer la figure du flocon de Von Koch, ci dessous: \n", + "![image](./images/FloconVK.png) \n", + "Cette construction se décompose ainsi: \n", + "![image](./images/DecomposeFlocon.png) \n", + "Ainsi en observant la composition du segment d'ordre 0, à gauche, on en déduit le L-system suivant:\n", + "- Axiome : F\n", + "- Règle : F —> F+F--F+F \n", + "Avec : F —> variable (commande *forward* de la tortue) \n", + "Et deux constantes : \n", + "- \\+ —> rotation de +60° de la tortue; \n", + "- \\- —> rotation de -60°. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Écrire le L-system d'un segment du flocon de Von Koch :

" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "##### Segment du flocon de Von Koch: #####\n", + "\"\"\"\n", + "alphabet:\n", + " variable: F\n", + " constantes: +;-\n", + "axiom: F\n", + "règle: F —> F+F--F+F\n", + "\"\"\"\n", + "\n", + "def iter_lSystem(chaine: str, k: int) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne initiale (l'axiome) et l'ordre k souhaité\n", + " Retourne la chaîne obtenue après k applications du L-system\n", + " \"\"\"\n", + " for _ in range(k):\n", + " chaine = lSystemConvert(chaine)\n", + " return chaine\n", + "\n", + "def lSystemConvert(chaine: str) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne de caractères\n", + " Retourne la chaîne obtenue après application des règles du L-System\n", + " \"\"\"\n", + " rules = {\"F\":\"F+F--F+F\"} # A compléter : règles\n", + " result = ''.join([rules.get(ch, ch) for ch in chaine]) # A compléter : liste par compréhension et ''.join()\n", + " return result\n", + "\n", + "axiome = 'F'\n", + "\"\"\"\n", + "for k in range (5):\n", + " print(f'{k} => {iter_lSystem(axiome, k)}')\n", + "\"\"\"\n", + "\n", + "resultat = iter_lSystem(axiome, 2)\n", + "\n", + "from turtle import Pen\n", + "\n", + "t = Pen()\n", + "for instruction in resultat:\n", + " if instruction == '+':\n", + " t.right(60)\n", + " elif instruction == '-':\n", + " t.left(60)\n", + " elif instruction == 'F':\n", + " t.forward(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Le flocon :

\n", + "\n", + "A partir du tracé d'un côté, la forme fermée du flocon est obtenue en partant d'un triangle équilatéral : \n", + "![image](./images/Triangle.png) \n", + "\n", + "Adapter l'axiome du L-system pour obtenir la chaîne de commande du flocon." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "##### Flocon de Von Koch: #####\n", + "\"\"\"\n", + "alphabet:\n", + " variable: F\n", + " constantes: +;-\n", + "axiom: \n", + "règle: F —> F+F--F+F\n", + "\"\"\"\n", + "\n", + "def iter_lSystem(chaine: str, k: int) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne initiale (l'axiome) et l'ordre k souhaité\n", + " Retourne la chaîne obtenue après k applications du L-system\n", + " \"\"\"\n", + " for _ in range(k):\n", + " chaine = lSystemConvert(chaine)\n", + " return chaine\n", + "\n", + "def lSystemConvert(chaine: str) -> str:\n", + " \"\"\"\n", + " Prends en entrée une chaîne de caractères\n", + " Retourne la chaîne obtenue après application des règles du L-System\n", + " \"\"\"\n", + " rules = {\"F\":\"F+F--F+F\"} # A compléter : règles\n", + " result = ''.join([rules.get(ch, ch) for ch in chaine]) # A compléter : liste par compréhension et ''.join()\n", + " return result\n", + "\n", + "axiome = '+F--F--F'\n", + "resultat = iter_lSystem(axiome, 4)\n", + "\n", + "#print(resultat)\n", + "\n", + "from turtle import Pen, exitonclick\n", + "\n", + "t = Pen()\n", + "\n", + "t.up()\n", + "t.goto(-300, -300)\n", + "t.down()\n", + "\n", + "t.speed(0)\n", + "t.color('#5B58A4', '#B5F8FF')\n", + "t.begin_fill()\n", + "for instruction in resultat:\n", + " if instruction == '-':\n", + " t.right(60)\n", + " elif instruction == '+':\n", + " t.left(60)\n", + " elif instruction == 'F':\n", + " t.forward(10)\n", + "t.end_fill()\n", + "exitonclick()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Commande du module Turtle :

\n", + "\n", + "Notre L-system permet d'obtenir la suite des commandes destinées à la tortue pour tracer le flocon de Von Koch. \n", + "Remarque : Il faut appliquer un facteur d'échelle $<1$ sur la commande` forward()` de la tortue, en fonction de l'ordre renvoyé par le L-system, afin de conserver un tracé qui tienne dans la fenêtre." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import turtle as trtl # https://docs.python.org/fr/3/library/turtle.html# \n", + "\n", + "def dessine (taille) :\n", + " trtl.pendown()\n", + " trtl.forward(taille)\n", + " trtl.right (90)\n", + " trtl.forward (taille)\n", + " trtl.right (90)\n", + " trtl.penup()\n", + "\n", + "taille = 20\n", + "for _ in range (10):\n", + " trtl.penup()\n", + " taille = taille * 1.2\n", + " dessine (taille)\n", + "trtl.exitonclick()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Applications :

\n", + "\n", + "Voici d'autres exemple de fractale à tracer avec votre algorithme L-System : " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from turtle import Pen\n", + "\n", + "# L'arbre binaire:\n", + "\n", + "def arbre_binaire():\n", + " pile = []\n", + "\n", + " arbre_binaire = {\n", + " 'longueur': 5,\n", + " 'angle': 18, \n", + " 'niveaux': 6,\n", + " 'axiome': 'X',\n", + " 'regles': { 'X': 'F[+X]-[-X]+', # Note: [ et ] —> enregistrer et restaurer la position de la tortue.\n", + " 'F': 'FF' }\n", + " }\n", + "\n", + " chaine = arbre_binaire['axiome']\n", + " for _ in range(arbre_binaire['niveaux']):\n", + " chaine = ''.join([arbre_binaire['regles'].get(ch, ch) for ch in chaine])\n", + "\n", + " t = Pen()\n", + " t.left(90)\n", + "\n", + " for instruction in chaine:\n", + " if instruction == '[':\n", + " pile.append(t.pos())\n", + " elif instruction == ']':\n", + " t.goto(pile.pop())\n", + " elif instruction == 'F':\n", + " t.forward(arbre_binaire['longueur'])\n", + " elif instruction == '+':\n", + " t.left(arbre_binaire['angle'])\n", + " elif instruction == '-':\n", + " t.right(arbre_binaire['angle'])\n", + "\n", + "\"\"\"\n", + "\n", + "\n", + "# Les arbres de la page 25 du livre The Algorithmic Beauty of Plants (http://algorithmicbotany.org/papers/abop/abop.pdf)\n", + "arbre_a = {\n", + " 'longueur': 4,\n", + " 'angle': 25.7, \n", + " 'niveaux': 5,\n", + " 'axiome': 'F',\n", + " 'regles': { 'F': 'F[+F]F[-F]F' }\n", + "}\n", + "\n", + "arbre_b = {\n", + " 'longueur': 9,\n", + " 'angle': 20, \n", + " 'niveaux': 5,\n", + " 'axiome': 'F',\n", + " 'regles': { 'F': 'F[+F]F[-F][F]' }\n", + "}\n", + "\n", + "arbre_c = {\n", + " 'longueur': 10,\n", + " 'angle': 22.5, \n", + " 'niveaux': 4,\n", + " 'axiome': 'F',\n", + " 'regles': { 'F': 'FF-[-F+F+F]+[+F-F-F]' }\n", + "}\n", + "\n", + "arbre_d = {\n", + " 'longueur': 3,\n", + " 'angle': 20, \n", + " 'niveaux': 7,\n", + " 'axiome': 'X',\n", + " 'regles': { \n", + " 'X': 'F[+X]F[-X]+X', \n", + " 'F': 'FF'\n", + " }\n", + "}\n", + "\n", + "arbre_e = {\n", + " 'longueur': 3,\n", + " 'angle': 25.7, \n", + " 'niveaux': 7,\n", + " 'axiome': 'X',\n", + " 'regles': { \n", + " 'X': 'F[+X][-X]FX',\n", + " 'F': 'FF'\n", + " }\n", + "}\n", + "\n", + "arbre_f = {\n", + " 'longueur': 7,\n", + " 'angle': 22.5, \n", + " 'niveaux': 5,\n", + " 'axiome': 'X',\n", + " 'regles': {\n", + " 'X': 'F-[[X]+X]+F[+FX]-X',\n", + " 'F': 'FF' \n", + " }\n", + "}\n", + "\n", + "\"\"\"\n", + "\n", + "arbre_binaire()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.8.10 64-bit", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}