Vektoren


 

Processing 2.0

Ein PVector ist ein Objekt, das 2- oder 3-dimensionale Vektoren beschreibt. Ein Vektor hat eine bestimmte Richtung und eine bestimmte Länge. Man kann auch sagen, er erstreckt sich vom Punkt A zum Punkt B. In der Programmierung verwenden wir Vektoren, um Bewegung zu generieren.

Der Vorteil bei der Verwendung von Vektoren liegt darin, dass man schon mit 2 Vektor- Variablen die aktuelle Geschwindigkeit und Richtung eines Objektes beschreiben kann und mit einem zweiten die Änderung derselben. Diese beiden müssen dann nur noch in jedem Frame addiert werden.

Beispiel: starte Applet

/** Copyright 2012 Thomas Koberger
*/

// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//hier werden die Vektoren erstellt
PVector direction = new PVector(1,1);
PVector position = new PVector(20,20);
int radius = 15;

void setup() {
size(300,300);
}

void  draw() {
//für den Schweif
fill(255,20);
rect(0,0,width,height);
//damit sich überhaupt was bewegt
position.add (direction);
//die nächsten Zeile lassen die Ellipse zurückprallen
if (position.x < radius || position.x > (width-radius)) {
direction.x *= -1;
}
if (position.y < radius || position.y > (height-radius)) {
direction.y *= -1;
}
//zeichnet die Ellipse
fill(50);
ellipse(position.x,position.y,radius*2,radius*2);
}

Das Ganze kann dann noch gut mit Zufallszahlen kombiniert werden.

Methoden:

  • vector.set(x,y,z) … legt die x-, y- und z-Werte des Vektors fest
  • vector.get() … gibt die x-, y- und z-Werte des Vektors zurück
  • vector.mag() … gibt die Länge des Vektors zurück
  • vector1.add(vector2) … Addiert 2 Vektoren
  • vector1.sub(vector2) … Subtrahiert 2 Vektoren
  • vector1.mult(float) … Multipliziert  einen Vektor mit einer Zahl
  • vector1.div(float) … Dividiert  einen Vektor durch eine Zahl
  • vector.nomalize() … Ändert die Länge auf 1
  • vector1.anglebetween(vector2) … gibt den Winkel zwischen 2 Vektoren zurück
  • vector.heading2D() … gibt die Richtung des Vektors zurück

Aufgabe: Verändere das Programm so, dass der Kreis zufällig seine Richtung leicht variiert.

Vektoren im 3 dimensonalen Raum

Richtig interessant wird die Verwendung von Vektoren in 3D. Auch hier können alle oben genannten Methoden verwendet werden. D.h., um beispielsweise ein Objekt an die Position eines Vektors zu verschieben geht man wie folgt vor:

PVector loc=new PVector(x,y,z);

translate(loc.x, loc.y, loc.z);
Dann wird das Objekt auf die Position (0,0,0) gezeichnet. Wir haben also das Koordinatensystem verschoben. Um das Koordinatensystem wieder an zurückzusetzten verwendet man pushMatrix() und popMatrix().

Da Objekte im Raum, aber nicht nur eine Position, sondern auch eine bestimmte Orientierung aufweisen, stellt sich schnell die Frage, wie man die Orientierung im Raum definiert.

In einer Fläche (2 Dimensionen) ist das raltiv einfach. Man braucht dafür nur einen Winkel. Dieser steht normal zur Fläche (siehe Bsp.).

Beispiel: Rotate 2D starte Applet

/** Copyright 2012 Thomas Koberger
*/

// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

PVector zero, actual;

void setup() {
size(300,300, P2D);
zero= new PVector(100,0);
rectMode(CENTER);
}

void draw() {
background(200);
stroke(0);

// Verschiebe das Koordinatensystem in den Mittelpunkt
translate(width/2, height/2);
line(0,0,zero.x,zero.y);

// Berechne die Koordinaten des Vektors actual aus der Mausposition
actual=new PVector(cos(map(mouseX,0,width,0,2*PI))*100,sin(map(mouseX,0,width,0,2*PI))*100);

stroke(200,0,50);
line(0,0,actual.x,actual.y);
text("Winkel:"+degrees(actual.heading2D()),height/2-130,width/2-30);

//Verschiebe das Koordinatensystem an die Position von actual
translate(actual.x,actual.y);

//Rotiere das Koordinatensystem
rotate(actual.heading2D());
rect(0,0,20,20);
}

Die Axis-Angle Methode

Im 3 dimensionalen Raum muss neben dem Winkel noch eine Achse angegeben werden, um welche gedreht wird. Wenn ich  sage, meine beiden Unterarme liegen  im Winkel von 90 zueinander, so würde sofort gefragt, in welcher Richtung. Ich könnte nämlich meine Arme in viele verschiedene Positionen drehen, und trotzdem könnten sie immer 90 zueinander liegen. Was wir brauchen ist die Definition einer Achse, um die gedreht wird.

Eine Methode, Axis-Angle Methode genannt, bietet die Möglichkeit beides, nämlich die Achse und den Rotationswinkel zu berechnen. Dabei kommen zwei mathematische Methoden zum Einsatz. Nämlich das sog. Punktprodukt od. Skalarprodukt (gibt den Rotationswinkel an) und das Kreuzprodukt, welches über einen neuen Vektor die Rotationsachse repräsentiert.

Beispiel: Axis-Angle Methode für Processing 2.0

Achtung: läuft mit Processing 2.0b6 nicht im Android Mode!!!

// von Thomas Koberger
/**
* MOUSE               : Rotation um die Achse zwischen Objekten
*
* KEYS
* Space               : neue Zufallswerte für Vektoren
*/
// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Damit die Szene rotiert und gezoomt werden kann
// Im Javascript auszukommentieren
import peasy.*;

// Im Javascript Mode auszukommentieren
PeasyCam cam;

PVector zero, left, right;

void setup() {
size(800, 800, P3D);

// Im Javascript auszukommentieren
cam = new PeasyCam(this, 0, 0, 0, 1000);

// Vektoren werden definiert
zero= new PVector(0, 0, 0);
left=new PVector(-width/4+random(-100, 100), random(-100, 100), random(-100, 100));
right=new PVector(width/4+random(-100, 100), random(-100, 100), random(-100, 100));
}

void draw() {
background(50);

// Im Javascript und Android Mode einkommentieren
//translate (width/2,height/2,0);
drawAxes(300);
stroke(255);
fill(200);

// Zeichne Würfel und Linien
line(left.x, left.y, left.z, right.x, right.y, right.z);
pushMatrix();
translate(left.x, left.y, left.z);
box(20);
popMatrix();
pushMatrix();
translate(right.x, right.y, right.z);
box(20);
popMatrix();
pushMatrix();
stroke(200, 0, 50);

// Verschiebe das Koordinatensystem an die Position right
translate(right.x, right.y, right.z);

// Kopie von left erstellen
PVector diff=new PVector(left.x, left.y, left.z);

// Differenzvektor berechnen
diff.sub(right);

// Koordinatensystem verschieben
translate(diff.x/2, diff.y/2, diff.z/2);
diff.normalize();

// Orientierung des mittleren Quaders festlegen
zero=new PVector(0, 0, 1);

// Achse und Winkel berechnen
float angle = acos(zero.dot(diff));
PVector axis = zero.cross(diff);

//Rotiere das Koordinatensystem
rotate(angle, axis.x, axis.y, axis.z);

// Rotiere um die Achse
rotateZ(map(mouseX, 0, width, -PI, PI));
drawAxes(50);
fill(50, 0, 200);
box(20);
popMatrix();
}

// Koordinatensystem zeichnen
void drawAxes(int scl) {
stroke(255, 0, 0);
line(-scl, 0, 0, scl, 0, 0);
text("+x", scl, 0, 0);
text("-x", -scl-30, 0, 0);
stroke(0, 255, 0);
line(0, -scl, 0, 0, scl, 0);
text("+y", 0, scl+30, 0);
text("-y", 0, -scl, 0);
stroke(0, 0, 255);
line(0, 0, -scl, 0, 0, scl);
text("+z", 0, 0, scl+30);
text("-z", 0, 0, -scl+30);
}

// Achse neu ausrichten
// für Javascript Mode auskommentieren
void keyPressed() {
if (key == ' ') {
left=new PVector(-width/4+random(-100, 100), random(-100, 100), random(-100, 100));
right=new PVector(width/4+random(-100, 100), random(-100, 100), random(-100, 100));
}
}

PVector – Einführung von Daniel Shiffman

Advertisements

3 Kommentare

  1. Pingback: Processing – Über dieses Weblog « processing – tutorial

  2. Pingback: Android App Pure Pong! « processing – tutorial

  3. Pingback: Flocking « processing – tutorial

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: