Stap 8: L-systeem fractals met turtle graphics
Teken een driehoek. Nu nemen elke regel van de driehoek en vervang deze door een lijn met een driehoekige bult op het. Herhaal deze procedure. Zoals op de afbeelding met animatie (publiek domein, gebaseerd op
), krijgt u een Koch-sneeuwvlok.
Dit kan worden gemodelleerd door een super-eenvoudig schildpad-grafisch programma. Stel dat F betekent "teken voorwaarts", en "+" en "-" draai van 60 graden tegen de klok in en met de klok mee, respectievelijk. Dan is de eerste driehoek kan worden getrokken door:
Dat wil zeggen, gaan, recht door 120 graden uit te schakelen, ga dan naar voren, rechts door 120 graden uit te schakelen, ga vooruit.
De driehoekige hobbel lijn kan worden getrokken door:
Dus is hier hoe we kunnen genereren een sneeuwvlok. We nemen de eerste schildpad programma F ++ F ++ F tot het opstellen van een driehoek. Elke F in het vertegenwoordigt een lijn. Dus vervangen elke F door F-F ++ F-F. Als we gaan, genereren we de Koch-sneeuwvlok.
Dit is een eenvoudig voorbeeld van een L-systeem. Het idee achter een L-systeem is dat we met een tekenreeks beginnen (in dit geval F ++ F ++ F), en vervolgens een heleboel regels hoe de tekens wijzigen (in dit geval de ene regel ter vervanging van F met F-F ++ F-F) in elke iteratie. We passen dit een bos van tijden en krijgen we een nogal ingewikkeld tekenreeks. Na twee iteraties in het geval van sneeuwvlok krijgen we bijvoorbeeld:
Na vier krijgen we de afbeelding hierboven. (Om echt te krijgen een fractal, de lijnen moeten krimpen met elke iteratie, maar dat zal niet werken in Minecraft.)
Er is een heleboel echt goede informatie in dit gratis PDF boek.
Ik schreef een zeer eenvoudige lsystem.py module. Ter uitvoering van de sneeuwvlok, beginnen met standaardtekst:
Nu moeten we om de regels te definiëren. De afrondingsregels is door een python woordenboek:
Daarna definiëren we het keuzeaxioma, of startpunt:
Tot slot moeten we vertellen het systeem wat elk van de symbolen in het gemiddelde van de tekenreeksen. Voor verschillende L-systemen, we zullen verschillende betekenissen aan toe te wijzen (rotaties door verschillende hoeken, bijvoorbeeld). We moeten dus een tweede python woordenboek opgeven wat voor elk symbool is gedaan. Als u niet een actie voor een symbool opgeven, wordt het symbool genegeerd wanneer is het tijd voor de schildpad te trekken van de output (maar het is belangrijk voor de generatie). De betekenissen worden gegeven door een woordenboek dat aangeeft een functie om te bellen voor elk symbool. Één regel functies kunnen worden opgegeven met de lambda -operator. In dit geval zijn alle functies one-liners:
Tot slot roepen we de L-systeem, die aangeeft hoeveel iteraties (in dit geval 4):
Er is een speciale truc voor sommige L-systemen. Deze L-systemen worden raster uitgelijnd, met alle de rotaties wordt 90 graden. De vierkante curve (squarecurve.py) en de draak curve (dragoncurve.py) zijn mooie voorbeelden. De truc is om te bellen, ergens in de buurt van het begin van uw code:
Dit uw schildpad beweegt naar een integer raster locatie, en de kop in de richting van een raster uitgelijnd. Hierna blijft de schildpad precies raster uitgelijnd mits u het verplaatsen alleen met integer bedragen (bijvoorbeeld 7 niet 7.1, en niet zelfs 7. of 7.0 als deze zijn zwevend punt in Python), en u draaien alleen door een geheel getal: bedragen die veelvouden van 90 graden (b.v.,-180, of 90, maar niet 90.0 of 45 zijn). De draak kromme code geeft ook een voorbeeld van een voorwaartse functie die is een beetje ingewikkelder--in plaats van enkel een lijn, een muur met een opening in het trekt.
Eigenlijk kan roepen gridalign() soms een goed idee zelfs als niet alle van uw hoeken haaks zijn. Zul je waarschijnlijk krijgen enkele problemen van afrondingsfouten in een groot beeld, maar het kan nog beter kijken. Zie het voorbeeld van spacefilling curve (weergegeven in paars gekleurd glas!).
L-systemen hoeft te zijn tweedimensionaal. U kunt het opnemen van symbolen die yaw, pitch en roll rotaties. Voor het ontwerpen van bomen, een nuttige truc is dat de stapel opdrachten: ' [' opslaan in de huidige tekening staat een stapel en ']' om het te herstellen. Dit zal van de module van de schildpad push() en pop() methoden gebruiken. Bijvoorbeeld, is hier een fragment van code voor het tekenen van een eenvoudige boom (ltree.py):
Denk aan de L als een blad (hoewel deze eenvoudige code niet eigenlijk het blad--dat zou moeten worden toegevoegd aan het woordenboek tekenen). We beginnen met FL, die bestaat uit een romp plus een blad. Dan vervangen wij elk blad door [^ FL] > [^ FL] > [^ FL]. Dit is een set van drie takken, elk gekanteld door 20 graden uit de kofferbak, 120 graden uit elkaar. De haakjes zorgen ervoor dat na elk nieuw ^ FL is getekend, zijn we terug waar we waren vóór het. Dit wordt herhaald, zodat de bladeren op de takken worden vervangen door triples van takken, enzovoort.
Een meer realistische boom hadden meer complexe code voor ' ['. Het kon maken van de volgende takken korter en dunner, en hun materiaal te veranderen als we dichter bij de bladeren (en vervolgens terugzetten op ']'). Ik ook zo'n een boom als de manifestatiecode in lsystem.py, op basis van regels (met enkele aanpassingen) van De Geeky Blogger.
Ook kan je 3D dingen raster uitgelijnd. Hilbert.py heeft bijvoorbeeld een 3D Hilbert-curve.
Ten slotte, wilt mogelijk voeren sommige randomisatie in de regels van de L-systeem. Tot nu toe onze regels waren deterministische: één tekenreeks kreeg die vervangt een symbool, bijvoorbeeld 'F': ' F-F ++ F-F'. Maar in plaats van een eenvoudige vervangingstekenreeks, men een Python lijst van paren (p, string), waar p is een kans (van 0 tot 1) en de tekenreeks is de string moet worden gebruikt met deze kans kan geven. De waarschijnlijkheid van een bepaalde bron symbool had beter niet toevoegen tot meer dan 1, maar ze kunnen oplopen tot minder dan één--in dat geval is er een kans dat er geen vervanger zal zijn. Bijvoorbeeld, is hier een lichtjes gerandomiseerde versie van geeky .blogger de boom:
Deze regel heeft een 55% kans op een A vervangen door de structuur van een drie-tak, en een 25% kans op het vervangen van een twee-tak-structuur. Dit is niet zeer willekeurige--meer willekeur zou maken van dingen nog meer levensecht. Ik hecht een screenshot van een vrij schaars forest willekeurig gegenereerd met behulp van deze regel (en willekeurige plaatsing van bomen, onder voorbehoud van een minimale afstand).