Processing: Transformationen des Koordinatensystems, Teil 1

Wann immer man in Processing ein Rechteck, eine Ellipse oder eine Linie zeichnen will, muß man die Koordinaten für die jeweiligen Positionen angeben:

rect(xPositon, yPosition, breite, hoehe);
ellipse(xPosition, yPosition, xDurchmesser, yDurchmesser);
line(xPosition1, yPosition1, xPosition2, yPosition2);

Die Einheiten der Koordinaten werden in Pixeln angegeben, und der Ursprung des Koordinatensystems befindet sich (anders als wir es aus dem Mathematikunterricht kennen) in der oberen linken Ecke. Das folgende Programm gibt die x- und y-Koordinaten des Mauszeigers innerhalb des Programmfensters aus, das eine Größe von 400 * 400 Pixeln hat. x:0, y:0 ist in der oberen linken Ecke, x:400, y:400 unten Rechts, x: 200, y: 200 genau in der Mitte und so weiter.

Processing bietet die Möglichkeit, das Koordinatensystem zu verschieben (translate), zu skalieren (scale) und zu drehen (rotate). Um im Folgenden besser sehen zu können, was diese drei sehr nützlichen Methoden bewirken, haben wir eine kleine Methode zur Orientierung gebastelt, die ein Quadrat zeichnet, dessen Breite und Höhe genau die Häfte der Abmessungen des Programmfensters beträgt, und in das ein Pfeil gezeichnet ist, der von Links nach Rechts zeigt. Ohne eine Verschiebung des Koordinatensystems mittels translate befindet sich die Mitte dieses Quadrates am Ursprung des Koordinatensystems, also bei x: 0, y:0.

Koordinatensystem verschieben mit translate()

Im ersten Beispiel wird innerhalb der draw-Methode mit translate(mouseX, mouseY) (Zeile 9) jeweils die x- und y-Position des Mauszeigers abgefragt und das Koordinatensystem an diesen Punkt verschoben, sodass sich der Ursprung immer genau an der Spitze des Mauszeigers befindet. Mit dem Verlassen eines Aufrufes von draw vergisst Processing die Verschiebung. Das gilt übrigens für alle Transformationen des Koordinatensystems.

void setup(){
  size(400, 400);
  frameRate(20);
  rectMode(CENTER);
}

void draw(){
  background(0);
  translate(mouseX, mouseY);
  orientierung(); 
}

void orientierung(){
  noFill();
  stroke(255);
  strokeWeight(10);
  rect(0,0, width/2, height/2);
  line(-width/4, 0, width/4, 0);
  line(width/4, 0, width/4 - 20, 20);
  line(width/4, 0, width/4 - 20, -20);
}

Koordinatensystem skalieren mit scale()

Im folgenden Beispiel wurde das Programm um die Möglichkeit erweitert, das Koordinatensystem mittels der Tasten + und - zu skalieren, also größer und kleiner zu machen. Damit das funktioniert, muß man einmal in das Programmfenster klicken:

float skalierFaktor = 1;

void setup(){
  size(400, 400);
  frameRate(20);
  rectMode(CENTER);
}

void draw(){
  background(0);
  translate(mouseX, mouseY);
  scale(skalierFaktor);
  orientierung();
}

void orientierung(){
  noFill();
  stroke(255);
  strokeWeight(10);
  rect(0,0, width/2, height/2);
  line(-width/4, 0, width/4, 0);
  line(width/4, 0, width/4 - 20, 20);
  line(width/4, 0, width/4 - 20, -20);
}

void keyPressed(){
  switch(key){
    case '+':
    skalierFaktor += 0.1;
    break;
    case '-':
    skalierFaktor -= 0.1;
    break;  
  }
}

In Zeile 1 wird die Variable skalierFaktor deklariert und mit dem Wert 1 initialisiert. Diese Variable wird in Zeile 12 an die Methode scale übergeben. Die Steuerung per Keyboard wird in den Zeilen 26-25 erledigt: Wenn eine Taste des Keyboards gedrückt wird (keyPressed()), wird geprüft, ob die zuletzt gedrückte taste (key) gleich + war – in diesem Fall wird skalierFaktor um 0.1 erhöht. Entsprechend wird bei - 0.1 vom skalierFaktor abgezogen. Die Reihenfolge der translate– und scale-Aufrufe ist wesentlich für das Ergebnis. In dem Beispiel wird zuerst verschoben, dann transformiert. Was passiert, wenn man die Reihenfolge umkehrt?

Koordinatensystem drehen mit rotate()

Zu guter Letzt bauen wir mittels der Methode rotate() die Möglichkeit der Rotation ein. Der Grad der Rotation wird mit der Kreiszahl Pi (= 3.14…) angegeben: Eine Rotation um den Betrag 2 * Pi bedeutet eine volle Drehung nach Rechts, entsprechend 1 * Pi eine halbe Drehung nach Rechts, 0.5 * Pi eine Vierteldrehung und so weiter. Negative Vorzeichen beschreiben eine Drehung nach links um denselben Betrag. Processing kennt übrigens die (hinreichend genauen) Werte von Pi und 2 * Pi, sie lassen sich mittels PI und TWO_PI in die Programme einbauen.

Im folgenden Programm kann man mittels der Keyboardtasten r und l das Qhadrat nach rechts und nach links drehen. Bitte beachten Sie wieder: Sie müssen einmal in das Programmfenster klicken, damit es funktioniert.

float skalierFaktor = 1;
float rotation = 0;

void setup(){
  size(400, 400);
  frameRate(20);
  rectMode(CENTER);
}

void draw(){
  background(0);
  translate(mouseX, mouseY);
  scale(skalierFaktor);
  rotate(rotation);
  orientierung();
}

void orientierung(){
  noFill();
  stroke(255);
  strokeWeight(10);
  rect(0,0, width/2, height/2);
  line(-width/4, 0, width/4, 0);
  line(width/4, 0, width/4 - 20, 20);
  line(width/4, 0, width/4 - 20, -20);
}

void keyPressed(){
  switch(key){
    case '+':
    skalierFaktor += 0.1;
    break;
    case '-':
    skalierFaktor -= 0.1;
    break;
    case 'r':
    rotation += 0.1;
    break;
    case 'l':
    rotation -= 0.1;
    break; 
  }
}

In Zeile 2 wird eine Variable rotation für die Rotation deklariert und mit 0 initialisiert. In Zeile 14 wird die Rotation durchgeführt. Die Änderung des Wertes von rotation erfolgt (ähnlich wie im vorigen Beispiel für den skalierFaktor) in den Zeilen 36-41. Auch hier gilt: die Reihenfolge der Transformationsbefehle ist wesentlich für das Ergebnis!