Python Library Turtle Rekursion Baum?

3 Antworten

Orientiere Dich an einer Routine, die alle Knoten eines Baumes durchläuft, strukturell ist es genau das gleiche. Der Knoten wird einfach durch eine Linie ersetzt, dann jeweils mit Drehung linker und rechter Nachfolger rekursiv gezeichnet. Mehr ist es nicht.

Christoph12423 
Fragesteller
 24.09.2020, 20:47

Bräuchte den Code, weil ich nicht weiß, wie ich das angehen soll. Wäre sehr dankbar.

0
KarlRanseierIII  24.09.2020, 20:51
@Christoph12423

Selbst ist der Mann. Hättest Du gestern Deine rekursive Spirale selbst gelöst, würde Dir das jetzt ruckzuck von der Hand gehen.

1
Christoph12423 
Fragesteller
 24.09.2020, 20:59
@KarlRanseierIII

Na ja, der Baum ist zumindest für mich etwas komplexer als die Spirale. Ich habe ein paar Ansätze zur Lösung (Funktion definieren etc.), aber in diesem Fall bin ich wirklich hilflos, weil ich gar nicht weiß, wie ich das umsetzen soll. Die Spirale verstehe ich jetzt schon besser, aber das heißt nicht, dass ich den Baum jetzt „ruckzuck von der Hand“ zeichnen kann.

Ich bin kein großer Experte und im Informatikunterricht wurde das Thema Rekursion bis jetzt nicht behandelt, aber es wird verlangt. Mein Ziel ist es, das am Ende zu verstehen, aber ich bräuchte mal einen Code zum Anfangen.

0
KarlRanseierIII  24.09.2020, 21:24
@Christoph12423

Falscher Ansatz, erst die Rekusion verstehen, dann der Code.

Wenn die Grundlagen von Rekursion fehlen, dann nachholen.

Bei der Rekursion baust Du darauf, daß alle lokalen Variablen einer Funktion als Zustand auf dem Stack erhalten bleiben, bis Du aus dem Abstieg wiederkehrst.

Ein n-ärer Baum ist immer eine rekursive Struktur, hier sollst Du diese Struktur für den binären Fall visualisieren.

Schaue das Bild genau an, der Baum der Tiefe 1 besteht aus dem Stamm. Tiefe 2, Stamm und zwei Ästen, jeder Ast ist im Endeffekt ein Stamm, nur etwas kürzer. Das wiederholt sich immer wieder mit steigender Tiefe.

Jetzt überlege Dir, wie Du diesen Baum ablaufen würdest, denn genauso zeichnest Du ihn am besten auch:

Eine Linie zeichnen, Position merken, nach links die Abzweigugn runter, Position wieder herstellen, rechts die Abzweigung runter. Das Speichern der Position ist die Erhaltung des Zustandes von der ich sprach. Alternativ könntest Du auch rückwärts laufen.

Und jetzt bildest Du das genau ab:

rekursion(parameter){
     stift ab;
     vorwärts;
     stift hoch;
     zustand speichern;
     links;rekursion(aktualisierte parameter);
     zustand wiederherstellen;
     rechts;rekusion(aktualisierte parameter);
     # zustand wiederherstellen; - ist nicht mehr nötig, weil hiernach kein weiterer Abstieg erfolgt.
     return;
}

Wie DU vielleicht siehst, wird der Abstieg (also der rekursiv aufruf) immer so weitergehen, damit das nicht passiert, ergänzen wir eine Abbruchbedingung:

rekursion(parameter, depth){
    if depth==0 return; #Abbruchbedingung
    ...
    rekursion(aktualisierte andere parameter, depth-1)
     ...
}

Bei jedem rekursiven Aufruf wird Tiefe also um 1 reduziert und sobald ich die Funktion mit Tiefe 0 aufrufe, wird gleich am Anfang abgebrochen.

So, und jetzt bildest Du das auf die Schnittstelle Deiner Turtlebibliothek ab und bist fertig.

3
Christoph12423 
Fragesteller
 25.09.2020, 18:38
@RakonDark
Ich hätte folgenden Code:

from gturtle import *

def tree(s):
    if s < 8:
        return
    forward(s)
    left(45)
    tree(s/2)
    right(90)
    tree(s/2)
    left(45)
    back(s)

makeTurtle()
setY(-100)
tree(128)

Was muss ich ändern, um den Baum wie auf dem Bild zu haben? Danke
0
RakonDark  25.09.2020, 18:45
@Christoph12423

naja was kann man da machen ,

wenn tree(128) machst zeichnet er das links rum, jetzt müsstest du dir anguckenw as muss den in der funktion geändert werden damit der aufruf zu einem rechts rum führt . das tolle an turtle ist , man brauch gar nciht programmieren können , sondern nur ein stift und den anweisungen folgen , buzw die zeichnung mit anweisungen umsetzen .
so wenn du weist wie deine andere funktion auszusehen hat musst du dir überlegen ob du einfach eine zweite funktion machst , also treeright(128) oder ob du das einfach mit einem parameter in deiner funktion machst und dann mit if (parameter = 0) > rechts Else links , oder halt durch berechnung oder oder . man kann es also ganz einfach lösen oder halt etwas nachdenken wenn es eher eine funktion bleiben soll .

0
KarlRanseierIII  25.09.2020, 19:23
@RakonDark

Ich habe es aus gutem Grudn abstrakt gemacht. Davon ab habe ich auf die Möglichkeit des Rückwärslaufens hingewiesen - allerdings kann das auch den Startpunkt verfehlen.

0

Ich schreibe dir jetzt auch keinen Code, aber mal grob, wie ich das verstehe.

Du musst ja Linien malen. Die haben einen Startpunkt, eine Länge, und einen Winkel. in dem Gezeichnet wird.

An Jedem Ende werden zwei neue Linien Gezeichnet. Eine um raten wir mal ~15° (ausprobieren!) weiter links und rechts. Diese sind dann auch kürzer.. die Hälfte?

Dann gäbe es ja zwei Möglichkeiten: Spaltenweise zeichnen (in die Tiefe). Also immer erst den linken Pfad rekursiv malen. Aber der Baum ist ja eig. unendlich tief. Also lieber in die Breite. Erst den Stamm, dann zwei zweige, dann die nächsten vier usw.

Ich würde mir, nachdem ich den Stamm habe vormerken, dass als nächsten 2 Äste mit start X und Winkel Y gemalt werden müssen.

Die Liste wird abgearbeitet. Für die Beiden Äste merkst du dir wieder vor, was als nächstes getan werden sollte usw.