Stap 16: Recursieve tekening
Tot nu hebben we de schildpad verteld waar getrokken en het heeft gedaan wat het was verteld - zelfs met meer ingewikkelde tekeningen zoals in het voorbeeld van de auto. Maar recursie geeft de schildpad een eigen leven. U vertellen wat te doen en dan achterover leunen en kijken.
Hier is een link naar Wikipedia's bespreking van recursie:
www.wikipedia.org/wiki/Recursion _ (computer_science...
Wat is recursie? Voor een persoon schrijven Arduino schildpad grafische functies, is het een andere manier van denken. Voor de schildpad die de tekening doet, is een zekere mate van onafhankelijkheid: "Just get me started en watch me gaan!"
Opmerking: de Arduino Uno heeft beperkte SRAM geheugen, maar nog steeds voldoende om recursie te gebruiken in onze voorbeelden turtle graphics. Als u probeert te gebruiken teveel recursieve stappen, uw functies werken mogelijk niet. Maar we hebben niet bereikt dat beperken in onze voorbeelden, dus laten we gaan vooruit en zien hoe dit werkt...
Wanneer we recursie roepen gebruiken wij een functie die zich roept. Hoe doen we dat? Het is het makkelijkst uit te leggen met een korte voorbeeld dat een V: trekt
nietig vee(length); Als u dit voorbeeld uitvoert, probeer het eens met een lengte van 80 pixels
{
t.Left(45); turnen links 45 graden
t.forward(length); tekent linkerarm van V met opgegeven - lengte 80 pixels, bijvoorbeeld
t.back(length); keert terug naar het begin punt van V
t.Right(90); draait rechts 90 graden - die is 45 graden naar rechts van de oorspronkelijke oriëntatie
t.forward(length); vestigt de rechterarm van V
t.back(length); keert terug naar het vertrekpunt
t.Left(45); keert terug naar de oorspronkelijke oriëntatie
}
Dat trekt er - een V. Nu zijn we klaar om toe te voegen van recursie. Na de eerste regel dat toevoegen t.forward(length); deze regel:
vee(length / 2); Dit is de recursie - een functie die zichzelf!
U hebt getrokken de linkerarm voor de V en nu u de dezelfde functie aanroepen om te trekken een ander V thats halve grootte. Nadat dat is voltooid, wordt de oorspronkelijke functie blijft tot het opstellen van de oorspronkelijke, grotere V. Dit is een interessante manier iets te tekenen. Het is eigenlijk een interessante manier van denken over hoe dingen kunnen worden getrokken.
Nu laten we het toevoegen van een kleinere V aan het einde van de rechterarm zo goed. Voeg deze regel weer na de tweede t.forward(length); :
vee(length / 2); Dit is de recursie - een functie die zichzelf!
We zijn bijna klaar, behalve voor een ding - de functie zal niet werken zoals die het is - er is iets om op te lossen. Recursie moet een stop-punt, zal niet het eindeloos doorgaan. (Deze de fout maakte ik toen ik voor het eerst geprobeerd tot het opstellen van een V met behulp van recursie - het werkte niet voor mij en ik had om advies te krijgen.) Voeg deze stop routine aan het begin van de functie:
Als (lengte < 10)
{
terugkeer;
}
Daar. Nu hebben we een stop-punt - wanneer de takken van de V zijn teruggebracht tot minder dan 10 pixels (Let op dat de lengte telkens wanneer de functie wordt aangeroepen is gehalveerd) - de functie stopt.
Hier is de volledige recursieve vee functie:
int lengte = 80; een variabele waarmee de lengte van de V's armen
nietig vee(length); namen van de functie, met één parameter, die de lengte van de zijden van de V is
{
Als (lengte < 10)
{
terugkeer; Dit stopt de recursie als lengte minder dan 10 pixels is!
}
t.Left(45); draait links 45 graden
t.forward(length); vestigt linkerarm van V met lengte van 80 pixels
vee(length / 2); Dit is de recursie - functie die zichzelf om te tekenen van kleinere V!
t.back(length); keert terug naar de onderkant van de V
t.Right(90); draait rechts 45 graden
t.forward(length); vestigt de rechterarm van V
vee(length / 2); Dit is de recursie weer!
t.back(length); keert terug naar het vertrekpunt
t.Left(45); keert terug naar de oorspronkelijke oriëntatie
}
Nu kunt u de functie. Probeer het met verschillende waarden voor de lengte van de V - kijken en zien wat er gebeurt!
VOORBEELD 1 - KEGELS
In dit voorbeeld wordt een functie die we hebben genoemd rCones wil twee bogen, t.arcLeft() en t.arcRight(), elk van 360 pixels in omtrek. Na het trekken van de eerste boog, de functie zichzelf aanroept (!-recursie)- en trekt een kleinere boog, 30 pixels korter in omtrek. Dit gaat zo door totdat de stop limiet is bereikt, wanneer de kleinere boog minder dan 100 pixels in omtrek is.
VOORBEELD 2 - EEN KLEINE BOOM
De voorbeeldfunctie van het rTree is vergelijkbaar met het bovenstaande voorbeeld van de V.
VOORBEELD 3 - EEN BOOM MET MEER TAKKEN
Deze maakt gebruik van dezelfde rTree functie gebruikt in voorbeeld 2, maar door het opgeven van een lange tak grootte de functie trekt veel meer takken. Het is interessant om te zien hoeveel detail kan worden toegevoegd door simpelweg het veranderen van deze één parameter.
VOORBEELD 4 - EEN COMPLEXERE BOOM
Het principe is hetzelfde - maar in deze functie zijn wij in staat om op te geven van de verschillende lengtes van de linker takken en de takken van het recht, en andere linker hoek en rechte hoek voor de takken. Ook de kortere einde takken worden getekend een andere kleur. Onze schildpad krijgt heel artistiek. Afhankelijk van de waarden is gebruikt, kan de resulterende afbeelding worden verfijnd. Probeer enkele tak van verschillende lengtes en kleuren en zien wat er gebeurt.
VOORBEELD 5 - RECURSIEVE DRIEHOEKEN
In het volgende voorbeeld worden Sierpiński driehoeken getekend. Lees meer over hen op Wikipedia: