Das Handwerkszeug zur visuellen Darstellung haben wir schon unter 2.2.4.3 gelernt. Hinzu kommt jetzt noch die Steuerung einer Canvas.
Erstellen wir eine Canvas (Put canvas) und geben ihr in den Properties (Rechtsklick auf die Box links oben in der Canvas) das receive-Symbol „c1“:
Nun können wir der Canvas Nachrichten senden:
Dies sollte aus dem Vorhergegangenen schon klar geworden sein: Ein sauberer Patch besteht aus Schaltfläche und Unterpatches (vgl. 3.4.2.4 und 5.1.1.1). In diesem Tutorial habe ich meist darauf verzichtet, da Sie das jeweils Erläuterte auf einer Grafik besser überblicken können.
Canvases dienen als farbliche Elemente, um einen Patch klarer zu unterteilen (siehe 3.4.2.4). Zur Anzeige von Funktionen lassen sie sich aber auch variabel einsetzen. Zum Beispiel können wir uns die Ergebnisse eines Zufallsgenerators anzeigen lassen:
patches/5-2-2-2-canvas-anzeige.pd
Wir können auch eine Zahl vergrößert darstellen (allerdings muss die Zahl grundsätzlich durch ein Symbol ergänzt werden, in diesem Beispiel „>“):
Die Möglichkeiten lassen sich fast beliebig erweitern, bis hin zur Erstellung ganzer grafischer Partituren mit Canvases.
Canvases können über andere GUI-Objekte gelegt werden; die Reihenfolge der Erzeugung ist dabei entscheidend. So kann man eigene Toggles erstellen:
Es wurde zuerst ein Toggle mit der Größe 55 erstellt, von dem die Verbindung zum „sel 1“ weggeht. Dann wurde ein Canvas der Größe 55 und ein receive-Symbol „cx“ erstellt und genau über den Toggle gesetzt (wichtig ist die Reihenfolge des Erstellens, sonst verschwindet die Canvas hinter dem Toggle). Das „sel 1“ und den Rest könnte man auch in einem Subpatch separieren und von dem Toggle intern ein „send“ einstellen.
Hier sind wiederum den Möglichkeiten keine Grenzen gesetzt. So lässt sich zum Beispiel eine Klavieroktave umsetzen (selbstverständlich gibt es begnadetere Pd-Grafikkünstler als mich):
patches/5-2-2-3-klavier-anzeige.pd
Der Subpatch enthält:
Hinter dem Klavier stecken eine Reihe von Bangs:
Eine eigene Abteilung für Grafik in Pd sind die Data Structures.
In einem Subpatch können wir grafische Elemente platzieren. Dazu erstellen wir zunächst den Subpatch „grafik“ und definieren für diesen Subpatch Variablen und eine Grafik. Wir nennen dies eine „Vorlage“. Sie erhält die Variablen mit „struct“; als Argument geben wir den Namen der Vorlage (hier „g1“) und dann immer jeweils Paare aus Typ und Name, in unserem Fall float x float y float q. „float“ ist der Typ (also eine Komma-Zahl), x, y, und q sind frei gewählte Namen.
Die Grafik können wir mit den vorhandenen Objekten „drawcurve“, „drawpolygon“, „filledcurve“ und „filledpolygon“ definieren. Nehmen wir für unser Beispiel „filledpolygon“. Ein Polygon ist ein Mehreck. Als erstes Argument gilt die Farbe innen, dann die Farbe des Randes, die Breite des Randes und dann Paare von Koordinaten-Punkten, angefangen links oben und weiter im Uhrzeigersinn.
Zum Erstellen der Grafik brauchen wir nun „append“. Es erhält als erstes Argument den Vorlagennamen und dann mögliche Variablen – x und y sollten immer dabei sein – außerdem als Input rechts zunächst die Stelle im Subpatch, an der die Grafik platziert werden soll. Wir müssen uns vorstellen, dass die grafischen Elemente im Subpatch wie eine Liste nacheinander aufgereiht sind. „append“ muss zunächst den Platz in der Liste wissen, den ihm das Objekt „pointer“ benennt. „pointer“ geben wir die Message „traverse pd-grafik“; damit geht „pointer“ ganz an den Anfang der Liste. Mit der Message „bang“ wird dieser Listenplatz nun ausgegeben (an „append“). Daraufhin geben wir „append“ im linken Inlet Daten für die Variablen von „append“.
patches/5-2-3-1-data-structures1.pd
Um es noch einmal zu verdeutlichen: „x“ und „y“ sind spezielle Namen für ein grafisches Element bei den data structures. Damit wird die absolute Position festgelegt, 50/50. Wir haben nun ein „filledpolygon“ erzeugt mit der Innenfarbe 22, der Randfarbe 12, der Randbreite 3 und mit 4 Punkten: links oben, mit Abstand 0/0 von der absoluten Position, rechts oben mit Abstand 100/0 von der absoluten Position, rechts unten mit 100/100 und links unten mit 0/100. Würden wir die letzten zwei Zahlen einfach aus „filledpolygon“ entfernen, hätten wir nur noch ein Dreieck. Ebenso kann man eine Fläche mit beliebig vielen Ecken erzeugen.
Mit „traverse pd-grafik“ sind wir quasi ganz an den Anfang des Subpatches „grafik“ gegangen; mit „bang“ wurde dieser Platz an „append“ gegeben und append legt dann an dieser Stelle, wenn wir ihm Daten für die Variablen geben, die Grafik an.
Wir können nun aber auch an dieser Grafik etwas ändern. Wir haben ja für die Vorlage „g1“ noch die Variable „q“ (ein float) bestimmt. Geben wir nun für das filledpolygon ein: „filledpolygon 22 12 3 0 0 q 0 100 100 0 100“. Ein Punkt hat nun eine Variable. Daraufhin veschwindet der Punkt zunächst und wir haben nur noch ein Dreieck. Diesen variablen Punkt können wir mit „append“ einstellen:
patches/5-2-3-1-data-structures2.pd
... aber auch mit „set“. Dies muss ebenso von dem pointer die Information erhalten, an welcher Stelle im Subpatch etwas geändert werden soll. In dem Fall ist es ein Schritt nach dem Beginn. Wir gehen mit „traverse pd-grafik“ ganz an den Anfang. Der Anfang ist unbesetzt; mit „next“ gehen wir an die sodann gesetzte Grafik. Nun können wir im linken Input für q einen Wert eingeben.
patches/5-2-3-1-data-structures3.pd
Mehrere Grafiken legen wir einfach mit mehreren Messages für „append“ an. Nun geht man mit „next“ von einer zur nächsten.
patches/5-2-3-1-data-structures4.pd
Zu den anderen grafischen Elementen: „drawpolygon“ ist einfach nur eine Linie, die mit Ecken verläuft; das erste Argument mit der Innenfarbe fällt weg. Ebenso verhält sich „drawcurve“, bei dem die Ecken des Strichs abgerundet sind. „filledcurve“ wiederum schließt die Fläche und hat als erstes Argument die Innenfarbe.
patches/5-2-3-1-data-structures5.pd
Dazu sei noch ergänzt: Die (Eck)Punkte einer Grafik, die Variablen haben, kann man mit der Maus verändern; der Cursor ändert sein Erscheinungsbild an der entsprechenden Stelle und der Punkt lässt sich bei gedrückter Maustaste bewegen.
Setzt man mit „append“ ein grafisches Objekt, gibt es als Output einen neuen Pointer-Verweis genau auf dieses Objekt (wie „next“):
patches/5-2-3-1-data-structures6.pd
Ein pointer-Verweis ist übrigens eine eigene Art von Information, zum Beispiel für „trigger“:
patches/5-2-3-1-data-structures7.pd
Mit „get“ können wir nun auch die Daten von grafischen Elemente empfangen, angeschlossen an den Pointer:
patches/5-2-3-1-data-structures8.pd
Zuletzt kann man auch einen (grafischen) Array mit data structures erzeugen. Der Array wird in „struct“ definiert, und zwar durch einen Namen und eine weitere zugewiesene Vorlage. Mit „plot“ geben wir diesem Array Farbe, Breite, Startpunkt (x/y) und Punkteabstand.
In einem anderen Subpatch muss dazu noch die weitere Vorlage, die die Variablen des Arrays bestimmt, enthalten sein:
Die Variable „y“ wird automatisch als Höhe des Arrays verstanden. Diese Variable ist notwendig, um den Array richtig zu erstellen.
Nun erzeugen wir den Array:
patches/5-2-3-1-data-structures9.pd
Mit „setsize“ ändern wir die Größe:
Und über einen Umweg ändern wir die Variable „y“: Mit „element“ erhalten wir den Zugang.
Eventuell wird sich die Gestalt der data structures in Zukunft noch ändern (Stand Juni 2008). Des Weiteren sind noch einige Spezialfunktionen für die data structures in der originalen Pd-Dokumentation zu sehen.
Wie schon vorab sei auch in diesem Zusammenhang erwähnt, dass es für Pd ein Zusatzprogramm zur Videoerzeugung namens GEM gibt.