Das Turtle Teachpack
Einleitung
Turtle-Grafik ist eine Methode zum Erstellen von Computergrafiken. Das Zeichnen wird dabei durch das Bewegen einer virtuellen Schildkröte über den Zeichenbereich modelliert. Eine Schildkröte kann durch drei Befehle bewegt werden:
(move n)
: Bewegt die Schildkröte um n Pixel ohne zu zeichnen.(draw n)
: Bewegt die Schildkröte um n Pixel und zeichnet dabei.(turn n)
: Dreht die Schildkröte um n Grad im Uhrzeigersinn.
Wir stellen jetzt ein Teachpack für DrScheme vor, mit dessen Hilfe solche Turtle-Grafiken erstellt werden können.
Installation
Sie können das Teackpack installieren, indem Sie im Menü
Sprache den Befehl Teachpack hinzufügen
wählen. Dann müssen Sie die Datei turtle.ss
den selbst installierte Teachpacks hinzufügen.
Tutorial
Unser Ziel ist es, in diesem Tutorial ein Quadrat mithilfe
der Funktionen des Teachpacks zu zeichnen. Aus diesem Grund
müssen wir zunächst mit der Prozedur
draw
eine Linie nach rechts malen.
Die initiale Ausgansposition der Turtle ist
in der Bildmitte mit Blick nach rechts.
Mit (draw 20)
bewegen wir die Turtle
dann 20 Pixel nach rechts und zeichnen dabei.
Um das resultierende Bild zu sehen ist, müssen
wir die Turtle mittels der Funktion
run
laufen lassen. Die restlichen Parameter für run
sind die Höhe und die Breite des Bildes sowie
die Farbe, in der gezeichnet werden soll.
Geben Sie also folgenden Befehl in die REPL ein,
um Ihre erste Turtle-Grafik zu erstellen:
(run (draw 20) 100 100 "red")
Sie erhalten dann eine Ausgabe wie die folgende:
Nun vervollständigen wir die Linie zu einem rechten Winkel: wir drehen die Turtle um 90° nach rechts und zeichnen dann eine Line der Länge 20 Pixel nach unten. Zum Drehen einer Turtle verwenden wir die Funktion turn.
Da wir ein Quadrat aus zwei rechten Winkeln
zusammensetzen können, abstrahieren wir
über das Zeichnen des rechten Winkels.
Dazu schreiben wir eine Prozedur
right-angle
die als
Parameter eine Turtle erhält:
; right-angle : turtle -> turtle (define right-angle (lambda (t1) (let* ((t2 ((draw 20) t1)) (t3 ((turn -90) t2)) (t4 ((draw 20) t3))) t4)))
Das Ergebnis sieht dann so aus:
Um das Quadrat komplett zu zeichnen, sollen nun zwei rechte Winkel verwendet werden. Wir zeichnen also einen rechten Winkel, drehen uns um 90° nach rechts, und zeichnen einen zweiten rechten Winkel.
; square : turtle -> turtle (define square (lambda (t1) (let* ((t2 (right-angle t1)) (t3 ((turn -90) t2)) (t4 (right-angle t3))) t4)))
So sieht das Ergebnis aus:
Verbesserungen
An dem Beispiel ist leicht zu sehen, dass es zum Zeichnen
mit Hilfe von Turtle-Grafik oft erforderlich ist,
Zwischenwerte wie t1
, t2
etc.,
an die nächste Funktion weiterzureichen, die Werte
ansonsten aber nicht weiterverwendet werden.
Beispielsweise werden
in der obigen Definition von square
die Variablen t1
, ..., t4
nur gebraucht, um die Prozeduren
right-angle
, (turn -90)
und right-angle
hintereinander auszuführen.
Um solche Fälle einfach programmieren zu können, enthält das
Turtle Teachpack die Prozedur
sequence. Damit können wir eine
zu right-angle
äquivalente Version
wesentlicher einfacher aufschreiben:
(define right-angle2 (sequence (draw 20) (turn -90) (draw 20)))Ebenso wie
right-angle
können wir square
leichter schreiben als:
(define square2 (sequence right-angle (turn -90) right-angle))
Funktionen
Funktionen, die das Teachpack bereitstellt:set-color
Diese Funktion ist eine Funktionsfabrik. Sie liefert
als Ergebnis eine Funktion, die auf eine
turtle
anwendbar ist. Wendet man das
Ergebnis auf eine turtle
an, so ändert dies die
Farbe mit der gezeichnet wird.
set-color: color -> (turtle -> turtle)
Beispiel
Folgender Code
(define square3 (sequence right-angle (turn -90) (set-color "blue") right-angle))
liefert dieses Bild:
turn
Diese Funktion ist eine Funktionsfabrik. Sie liefert
als Ergebnis eine Funktion, die auf eine
turtle
anwendbar ist. Wendet man das
Ergebnis auf eine turtle
an,
so ändert sich die Blickrichtung
der Turtle um die gegebene Gradzahl gegen den Uhrzeigersinn.
turn: number -> (turtle -> turtle)
draw
Diese Funktion ist eine Funktionsfabrik. Sie liefert
als Ergebnis eine Funktion, die auf eine
turtle
anwendbar ist. Wendet man das
Ergebnis auf eine turtle
an, so bewegt
sich die Schildkröte um die gegebene Anzahl
von Pixel und zeichnet dabei eine Linie.
draw: number -> (turtle -> turtle)
move
Diese Funktion ist eine Funktionsfabrik. Sie liefert
als Ergebnis eine Funktion, die auf ein
turtle
anwendbar ist. Wendet man das
Ergebnis auf eine turtle
an, so bewegt
sich die Schildkröte um die gegebene Anzahl
von Pixel, zeichnet dabei aber keine Linie.
draw: number -> (turtle -> turtle)
run
Diese Funktion wendet die übergebene
Funktion von turtle
nach turtle
auf die initiale Schildkröte an und zeigt das
daraus resultierende Bild an.
Der zweite Parameter ist die Höhe des Bilds,
der dritte Parameter die Breite des Bilds
und der vierte Parameter die Farbe, mit der
gezeichnet wird.
run: (turtle -> turtle) number number color -> image
sequence
Diese Funktion nimmt eine beliebige Anzahl
von Turtle-Veränderungen (d.h. Funktionen
mit Typ turtle -> turtle
)
und erstellt eine neue Funktion, die die Veränderungen
der Reihe nach von links nach
rechts abarbeitet.
sequence: (turtle -> turtle) ... -> (turtle -> turtle)