animatedFlower

In diesem Workshop beschäftigen wir uns mit dem Code, der diese Blume dynamisch zeichnet.

Vorbereitung

Als Erstes muss Processing installiert werden: https://processing.org/

Die wichtigsten Befehle zu Processing sind hier erklärt: kurzes Intro, es lohnt sich, das zuerst durchzulesen.

Erste Schritte

Versuch mit den Information zu Processing einen Teil der Blume wie auf dem Bild rechts zu zeichnen.

+ Hinweise:

  • Die Grösse des Zeichenfelds ist nach wie vor 400x400 Pixel.

  • Das gelbe Blütenblatt ist eine Ellipse mit einer Länge von 80 und einer Höhe von 200 Pixel.

  • Der schwarze Kreis der Blüte hat einen Radius von 100 und liegt genau in der Mitte.

  • Das gelbe Blütenblatt hat eine Deckkraft von 100.

flower1
Es kommt darauf an, in welcher Reihenfolge, die Elemente gezeichnet werden.
Lösungshinweis
1
2
3
4
5
size(400,400);
fill(255,255,0,100);
ellipse(200,300, 80, 200);
fill(0);
ellipse(200,200,100,100);

Transformationen

Damit ist der Anfang der Blume vorhanden. Es braucht allerdings noch weitere Blütenblätter. Die Blütenblätter für die anderen 3 Himmelsrichtungen wären wahrscheinlich relativ einfach zu bestimmen. Durch Hinzufügen von ellipse(100,200, 200, 80); entsteht z. B. das Blütenblatt nach Westen.

flower2

Aber wie zeichnen wir die Blütenblätter dazwischen, z. B. das Blatt, das nach Südsüdwest zeigt?

Rotation

Die Blütenblätter zwischen den 4 Richtungen können nicht einfach so gezeichnet werden, sondern müssen rotiert werden.

Dazu stellt uns Processing die Funktion rotate(radians) zur Verfügung. Wir sind uns vielleicht eher gewohnt, Winkel in Grad und nicht in Radiant anzugeben. Es gibt Umrechnungsmethoden in Processing, es ist aber einfach Radiant im Verhältnis zu PI anzugeben. Ein Radiant entspricht einem Kreis, also 360°. Das bedeutet, wir können Radianten auch mit Pi ausdrücken.

1 rad = 2*PI.

Für 16 Blütenblätter bedeutet das, dass sie jeweils um einen Winkel von 360°/16 rotiert werden. Ausgedrückt in Radiant ist das 2PI/16 resp. PI/8.

Die Methode rotate(); wird vor dem Zeichnen des nächsten Elements aufgerufen und betrifft alles, was nachher gezeichnet wird.

Wenn wir vor dem nächsten Blütenblatt rotate(PI/8); aufrufen, gibt es das folgende Resultat:

1
2
3
4
5
6
7
size(400,400);
fill(255,255,0,100);
ellipse(200,300, 80, 200); // Süden
rotate(PI/8);
ellipse(200,300, 80, 200); //SüdSüdWest
fill(0);
ellipse(200,200,100,100);
flower3

Das ist allerdings nicht das gewünschte Resutat.

Der Grund ist, dass in Processing nicht die Elemente rotiert werden, sondern das Koordinatensystem und zwar immer um seinen Nullpunkt.

flower3a

Translation (Verschiebung)

Wenn immer um den Nullpunkt des Koordinatensystems rotiert wird, muss der Nullpunkt an den gewünschten Ort verschoben werden. Genau das macht die Methode translate(x,y);.

Die Verschiebung des Nullpunkts hat Auswirkungen auf die Koordinaten der Elemente, d. h. die Ellipse des Blütenblatts beginnt nun bei (0,100);

1
2
3
4
5
6
7
8
size(400,400);
fill(255,255,0,100);
translate(200,200); (1)
ellipse(0,100,80,200); (2)
rotate(PI/8);
ellipse(0,100,80,200); (3)
fill(0);
ellipse(0,0,100,100); (4)
1 verschiebt
2 1. Ellipse hat neu den Mittelpunkt (0|100)
3 Nach der Rotation wird die gleiche Ellipse gezeichnet
4 Der schwarze Kreis hat neu den Mittelpunkt (0|0)
flower4

Animation

Um eine vollständige Blume zu erhalten, könnten die Zeilen 5 und 6 vom vorherigen Source Block 14 mal wiederholt werden. Auch wenn wir dazu eine Schleife benutzen um Wiederholungen programmieren, so erhalten wir keine animierte Blume.

Für interaktive Programme und Animationen werden sogenannte Frames verwendet. Frames werden in regelmässigen Abständen immer wieder aufgerufen. Processing kennt dafür die eingebaute Methode draw(). Code in dieser Methode wird in jedem Frame ausgeführt, dabei werden vorhandene Elemente überzeichnet.

Weil nicht aller Code mehrmals ausgeführt werden muss, gibt es die Methode setup(), die zu Beginn des Programms genau einmal ausgeführt wird.

Für unsere animierte Blume nutzen wir diese Möglichkeiten und schreiben unseren Code etwas um.

In der setup() Methode setzen wir die Grösse des Zeichenfensters und die Hintegrundfarbe auf Schwarz mit background(0);. Ausserdem verlangsamen wir die mit der Methode frameRate(5).

Die Blume zeichnen wir in der Methode draw(). Es wird nur ein Blütenblatt gezeichnet, allerdings jedes Mal in einem anderen Winkel. Die Grösse des Winkels können wir verändern, indem wir den Basiswinkel (PI/8) mit einer Zählvariable i multiplizieren. So wird ein Blütenblatt nach dem anderen gezeichnet. Am Schluss zeichnen wir noch die schwarze Blütenmitte.

Die Animation läuft endlos, durch das mehrmalige Zeichnen der Blütenblätter wird das Gelb immer weniger transparent.

Die Variable muss ausserhalb der Methode initialisiert werden, damit das Hochzählen funktioniert.
flowerFinal
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
void setup(){
  size(400,400);
  frameRate(5);
  background(0);
}
int i = 0;
void draw(){
  fill(255,255,0,100);
  translate(200,200);
  rotate(i*PI/8);
  ellipse(0,100, 80, 200);
  fill(0);
  ellipse(0,0,100,100);
  //translate(-200,-200);
  i++;
}

Die kommentierte Zeile 14 muss beim Verwenden des Web-Editors auskommentiert werden, weil da die Rücksetzung des Koordinatensystems nicht automatisch geschieht.

Herzliche Gratulation zum ersten Processing Programm.

Wie weiter?

Die Blume kann verändert werden, z. B. durch

  • die Anzahl Blütenblätter durch Ändern des Basiswinkels, z. B. PI/4 oder PI/16.

  • die Farbe der Blume

  • die Form der Blütenblätter.

Weiterführende Informationen, Beispiele und Lernmaterialien findest du über diese Seite Mehr zu Processing, Design und agile Softwareentwicklung.