Etape 8: Fractales système L avec des graphismes de tortue
Dessiner un triangle. Maintenant, prenez chaque ligne du triangle et remplacez-le par une ligne avec une bosse triangulaire à ce sujet. Répéter les étapes. Comme sur l’image animée (domaine public, basé sur
), vous obtenez un flocon de Koch.
Cela peut être modélisée par un programme Super-simple tortue-graphique. Imaginez que F signifie « tirer vers l’avant », et « + » et "-" tourner de 60 degrés, vers la gauche et vers la droite, respectivement. Puis le triangle initial peut être tiré par :
C'est-à-dire, aller de l’avant, tourner à droite de 120 degrés, puis allez vers l’avant, tourner à droite par 120 degrés, aller de l’avant.
La ligne de la bosse triangulaire peut être tirée par :
Voici donc comment nous pouvons générer un flocon de neige. Nous prenons le premier programme de tortue F ++ F ++ F dessiner un triangle. Chaque F qu’il représente une ligne. Donc, remplacer chaque F par et F ++ et F. Si nous continuons à avancer, nous générons le flocon de Koch.
Il s’agit d’un exemple simple d’un L-system. L’idée derrière un L-system est que nous commençons avec une chaîne de caractères (dans ce cas F ++ F ++ F), et puis un tas de règles comment faire pour changer les caractères (en l’occurrence, celle règle pour remplacer F avec et F ++ F-F) à chaque itération. Nous appliquons cela un tas de fois, et nous obtenons une chaîne assez compliquée. Par exemple, après deux itérations dans le cas de flocon de neige, nous obtenons :
Après quatre, nous obtenons l’image ci-dessus. (Pour vraiment obtenir une fractale, les lignes devraient se rétrécir à chaque itération, mais qui ne fonctionne pas dans Minecraft).
Il y a beaucoup d’informations très bonnes dans ce livre PDF gratuit.
J’ai écrit un module très simple lsystem.py . Pour implémenter le flocon, commencez par passe-partout :
Maintenant nous avons besoin de définir les règles. Je définis les règles par un dictionnaire python :
Ensuite, nous définissons l’axiome, ou point de départ :
Enfin, il faut indiquer au système ce que chacun des symboles dans la moyenne des chaînes. Pour L-systèmes différents, nous allons assigner un sens différent pour eux (rotations de différents angles, par exemple). Il faut donc un deuxième dictionnaire python en spécifiant ce qui se fait pour chaque symbole. Si vous ne spécifiez pas une action pour un symbole, le symbole est ignoré lorsqu’il est temps pour la tortue dessiner la sortie (mais il pourrait être important pour la génération). Les significations sont données par un dictionnaire qui spécifie une fonction à appeler pour chaque symbole. Fonctions d’une seule ligne peuvent être spécifiées avec l’opérateur lambda . Dans ce cas, toutes les fonctions sont one-liners :
Enfin, nous invoquons le L-système, en spécifiant le nombre d’itérations (dans ce cas 4) :
Il y a un truc spécial pour les L-systèmes. Ces systèmes de L sont alignés à grille, avec toutes les rotations en 90 degrés. La courbe de carrés (squarecurve.py) et de la courbe de dragon (dragoncurve.py) sont des exemples de nice. L’astuce consiste à appeler, quelque part vers le début de votre code :
Cela déplace ta tortue à un emplacement du réseau entier et aligne sa position à une direction de grille. Après cela, la tortue restera exactement la grille alignée autant que vous déplacer uniquement en montants entiers (p. ex., 7, 7.1 pas et même pas 7. ou 7.0 car ils sont la virgule flottante en Python), vous tournez uniquement par des montants entiers qui sont des multiples de 90 degrés (-180, ou 90, mais pas de 90,0 ou 45). Le code de courbe du dragon donne également un exemple d’une fonction avancée qui est un peu plus compliqué--au lieu de seulement une ligne, il dessine une cloison avec une ouverture en elle.
En fait, l’appel de gridalign() peut parfois être une bonne idée même si pas tous vos angles sont des angles droits. Vous obtiendrez probablement quelques problèmes d’arrondi dans une grande image, mais il peut toujours regarder mieux. Consultez l’exemple de courbe remplissant (rendu en vitrail mauve!).
L-systèmes ne doivent pas être à deux dimensions. Vous pouvez inclure des symboles qui lacet, tangage et rouler les rotations. Pour la conception des arbres, un truc utile est d’avoir des commandes de la pile: ' [' pour enregistrer l’état de dessin actuelle vers une pile et ']' pour le restaurer. Ceci utilisera du module turtle push() et pop() méthodes. Par exemple, voici un extrait de code pour dessiner un arbre simple (ltree.py) :
Pensez à la L comme une feuille (même si ce code simple n’est pas réellement la feuille--qui devrait être ajoutées au dictionnaire). Nous commençons par FL, qui est un tronc plus une feuille. Puis nous remplaçons chaque feuille de [^ FL] > [^ FL] > [^ FL]. Il s’agit d’un ensemble de trois branches, chacune incliné de 20 degrés dans le coffre, 120 degrés dehors. Les supports de ce que, après chaque nouvelle ^ FL est dessiné, nous sommes de retour là où nous étions avant elle. Cela se répète, afin que les feuilles sur les branches sont remplacés par les triples des branches et ainsi de suite.
Un arbre plus réaliste pourrait avoir un code plus complexe pour ' ['. Il pourrait faire les branches les plus courtes et plus minces et changer leur matériel que nous nous rapprochons de feuilles (puis restaurez sur "]'). Je comprend pas un tel arbre comme le code de démo dans lsystem.py, basé sur des règles (avec quelques réglages) depuis Le blogueur geek.
Vous pouvez aussi faire des choses 3D aligné à grille. Par exemple, hilbert.py a une courbe de Hilbert 3D.
Enfin, vous pourriez vouloir introduire certains randomisation dans les règles de L-système. Jusqu'à présent nos règles étaient déterministes : une chaîne unique qui remplace un symbole, par exemple, reçut « F »: ' et F ++ et F'. Mais au lieu d’une chaîne de remplacement simple, on peut donner une liste de Python de couples (p, string), où p est une probabilité (de 0 à 1) et string est la chaîne à utiliser avec cette probabilité. Les probabilités pour un symbole donné source n’avaient mieux pas ajouter jusqu'à plus de 1, mais ils peuvent s’additionner au moins un--dans ce cas, il y a une chance qu’il n’y aura aucun remplacement. Par exemple, voici une version un peu aléatoire d’arbre de Geek .blogger :
Cette règle a 55 % de chances de remplacer un A avec une structure à trois branches et 25 % de chance de le remplacer par une structure à deux volets. Ce n’est pas très aléatoire--plus aléatoire rendrait les choses encore plus réaliste. Je joins une capture d’écran d’une forêt assez clairsemée générée de façon aléatoire à l’aide de cette règle (et le placement aléatoire des arbres, sous réserve d’une distance minimale).