Advanced Games Physics
2. Kapitel

Positionierung von Objekten auf dem Bildschirm mittels Ko‍ordi‍nat‍en-Transformation

Klassische Koordinatentransformation

Um Objekte auf dem Bildschirm darstellen zu können, müssen sie positioniert werden. Wie wir in sahen, liefern unsere Berechnungen die Koordinaten für die darzustellenden Objekte. Nun müssen also diese Koordinaten den Pixelpositionen auf dem Bildschirm zugeordnet werden. Abbildung . zeigt wie die Pixel, deren Lage durch einen x- und einen y-Wert bestimmt sind, auf dem Bildschirm positioniert werden. Anders als wir das gewohnt sind, liegt der Nullpunkt in der linken oberen Ecke des Bildschirms und, was noch ungewöhnlicher ist, die y-Achse verläuft von oben nach unten.
Das bleibt nicht ohne Konsequenzen auf andere Koordinaten. So wird in "processing" oder "p5.js" auch der Drehsinn umgekehrt.
Bildschirm-Koordinatensystem
Abb. Bildschirm-Koordinatensystem
Geistesblitz
on/off



Geübte Programmierer haben sich so an diese Tatsachen gewöhnt, dass sie bei der Entwicklung ihrer Programme keine Probleme damit haben. Wem diese Besonderheiten aber zu unbequem erscheinen, dem gebe ich hier einige Transformationsregeln zur Hand, die die Computerwelt vom Kopf auf die Füße stellt und zudem noch weitere Vorzüge in sich vereinen.

Zunächst einmal ist es unvorteilhaft, wenn der Mittelpunkt einer Szene (entspricht dem Ursprung des Koordinatensystems) stets in der linken oberen Ecke liegt. Besser wäre es, einen frei wählbaren Mittelpunkt zu haben. Da wäre also zunächst eine Verschiebung des Ursprungs erforderlich. Was bedeutet das? Der Mittelpunkt meines gewünschten Koordinatensystems (kartesisches K. genannt) muss so in die Bildschirmkoordinaten (interne K. genannt) umgerechnet werden, dass die kartesischen Werte xk = 0 und yk = 0 in die internen Werte xi = 400 und yi = 300 umgerechnet werden, wenn der Ursprung des kartesischen Koordinatensystems genau in der Mitte des Fensters, das mit size(800, 600) (processing) oder createCanvas(800, 600) (p5.js) definiert wurde, liegen soll.
Bei dieser Gelegenheit wollen wir gleich den Makel des verkehrten Laufs der y-Achse mit beheben, das geschieht, indem wir eine Vorzeichenumkehr aller y-Werte vornehmen.
Koordinaten-Transformation
Abb. Koordinaten-Transformation
Geistesblitz
on/off

Die Transformationsgleichungen führen diese Operationen aus. Mit dem Index i werden die internen und mit dem Index k die kartesischen Koordinaten gekennzeichnet. Worin xi0 und yi0 die Lage des Ursprungs des kartesischen Koordinatensystems im internen Koordinatensystem bezeichnen ().
()
x i = x k + x i 0
y i = y k + y i 0


Aber auch die umgekehrte Transformation muss möglich sein. Denn eine Interaktion zwischen Spieler und Computer findet in der Regel mit Hilfe der Maus statt. Dazu werden neben den Maustasten vor allem die Mauskoordinaten abgefragt. Die Mauskoordinaten werden natürlich im internen Koordinatensystem angegeben. Also muss es eine Umrechnung interner in kartesische Koordinaten geben, damit die Mausparameter tatsächlich in die Szene passen. Die Transformation () stellen die umgekehrte Transformation dar.
()
x k = x i x i 0
y k = y i + y i 0
Geistesblitz
on/off


So sieht die Programm technische Umsetzung beider Transformationen in processing bzw. p5.js aus:



Abb. Programmauszug Koordinaten-Transformation

... und so werden die Transformationsfunktionen angewendet:



Abb. Transformation kartesich ↔ Koordinaten-Transformation

Im unteren Teil des Programmauszugs in wird gezeigt, wie die Transformation der Mauskoordinaten, die ja in internen Koordinaten und ohne Maßstab angegeben werden, in kartesische Koordinaten maßstabsrichtig umgerechnet werden. So kann ein Objekt (im Beispiel ein Kreis), das mit der Maus verschoben werden soll, auch in kartesischen Koordinaten plaziert werden. Das erleichtert das konsequente Rechnen in kartesischen Koordinaten.

Das Beispiel in zeigt, wie ein Rechteck abgebildet wird, dessen Koordinaten einmal im internen Koordinatensystem und einmal nach erfolgter Transformation im kartesischen Koordinatensystem angegeben werden. Das kartesische Koordinatensystem ist im Beispiel genau mittig angeordnet. Das ist zu sehen, wenn die Maus genau auf den Ursprung des Koordinatenkreuzes zeigt.

Fährt die Maus über die Koordinaten der Rechtecke, werden sowohl die internen wie auch nach Rücktransformation die kartesischen Koordinaten der Mausposition angezeigt. Mit den weißen Kreisen werden die Plazierungen des kartesischen Koordinatensystems bzw. der Rechtecke angedeutet. Während das rote Rechteck ohne Koordinaten-Transformation plaziert wird, wird das grüne Rechteck transformiert und maßstäblich plaziert. Alle Koordinatenwerte werden numerisch angezeigt!

Bitte einen Augenblick Geduld
während das Programm geladen wird!
Abb. Bildschirm-Koordinatensystem


ACHTUNG! In diesem Programmbeispiel wird ausnahmsweise mit einem nicht dynamischen Maßstab gerechnet, um die maßstäbliche Umrechnung von kartesischen in interne Koordinaten und umgekehrt zu demonstrieren. Deshalb kann es bei einigen Bildschirmauflösungen zu Beschneidungen des Darstellbereiches kommen!
download processing
download p5.js


Koordinatentransformation mit Hilfe der Matrix-Operationen

Wer mit Processing oder p5.js arbeitet, hat einen Vorteil. Beide Entwicklungsumgebungen bieten nämlich mit den Matrix-Befehlen (processing) bzw. (p5.js) einen besonderen Befehlssatz an. Dieser Befehlssatz erlaubt die selektive Kreation von Koordinatensystemen, die dank besonderer Befehle verschoben, rotiert und skaliert werden können. Auf diese Weise kannst Du Teile der Szenerie unabhängig von einander bewegen, drehen oder skalieren.

Aber beachte: für die Matrix-Befehle gelten für die y-Achse eine entgegen der positiven mathematischen Orientierung und für den Rotationswinkel eine entgegen den mathematisch positiven Winkeln definierter Drehsinn.

An dieser Stelle wollen wir die Matrix-Befehle zunächst nur für die Koordinatentransformation benutzen. Die Verwendung der Matrix-Befehle sollte nach einem strikten Ritual erfolgen: zuerst wird das bisher gültige Koordinatensystem im stack gesichert. Das besorgt die Anweisung pushMatrix() (processing) bzw. push() (p5.js), dann erfolgt die Generierung des neuen Koordinatensystems und die hierfür gedachte Szenerie wird implementiert. Ist das geschehen, wird das vorherige Koordinatensystem mit der Anweisung popMatrix() bzw. pop() wieder in Kraft gesetzt. Diese Reihenfolge ist unbedingt einzuhalten. Sollte in einem Programm einmal eine der beiden Anweisungen vergessen worden sein, dann rächt sich die Entwicklungsumgebung mit einem stackoverflow!

Das Programmbeispiel in zeigt, um wieviel bequemer die Programmierung durch die Anwendung der Matrix-Operationen wird. Denn die eigentliche Transformation wird durch den translate()- Befehl ausgeführt. Wenn xi0 und yi0 die Koordinaten des neuen Systems bezogen auf das Ursprungssystem (linke obere Ecke des Fensters) sind, dann können im verschobenen Koordinatensystem alle Koordinaten absolut angegeben werden.
Bleibt noch die Richtungsumkehr der y-Achse. Dafür stehen uns zwei Möglichkeiten zur Verfügung:
  1. Benutzung des Matrix/Befehls scale(1, -1);. Dieser Befehl bewirkt, dass alle x-Werte 1:1 übernommen, die y-Werte aber bei der Darstellung mit dem Faktor -1 multipliziert, also an der x-Achse gespiegelt werden.
    Achtung! Die Verwendung dieser Variante spiegelt alle Objekte in der Folge dieses Befehlts. Also auch Texte, Primitives oder Images!
  2. Bei der Darstellung eines Objektes werden alle y-Werte mit einem negativen Vorzeichen eingetragen. Das verursacht mehr Schreibarbeit umgeht aber das Spiegelungsproblem.
Im Programmauszug werden beide Varianten vorgestellt:



Abb. Koordinaten-Transformation mittels Matrix-Befehlen

Die Positionierung der Ellipse erfolgt nach der 1. Variante mit Hilfe des scale()-Befehls, die des Rectangles nach der 2. Variante durch Vorzeichenumkehr.
download processing
download p5.js

Kosmisches Beispiel für Nullpunkt-Transformation und Maßstabsbestimmung

Es soll die in gezeigte kosmische Konstellation Mond-Erde-Raumschiff auf dem Computerbildschirm dargestellt werden. In der oberen Hälfte der Abbildung sind die kosmischen Dimensionen wie Durchmesser bzw. Entfernung angegeben. Da das Raumschiff um die Erde kreisen soll, ist die Festlegung des Bahnmittelpunktes auf der Erdmittelpunkt zweckmäßig. Daraus folgt, dass der Nullpunkt des kosmischen Koordinatensystems mit den Mittelpunkten der Erde und der Flugbahn übereinstimmen sollte.


Maßstabsbestimmung
Abb. kosmisches Szenarium Erde-Mond-Raumschiff


In der unteren Hälfte der ist die auf Bildschirmverhältnisse (Bild-Welt) transformierte reale Welt gezeigt. Die Fenstergröße wurde mit 800 x 600 Pixeln festgelegt.

Zunächst wurden Vorgaben für die Wahl des Mittelpunktes der Erde in der Bild-Welt gemacht. Der Bild-Nullpunkt wurde mit xi0 = 650 Pixel und yi0 = 300 Pixel gewählt. Ebenso wurde die Entfernung vom Mond zur Erde mit 550 Pixeln festgelegt. Beide Festlegungen ergeben sich aus der Forderung, dass sowohl der Mond als auch die Erde maßstabsgerecht auf dem Bild zu sehen sein müssen. Nun können sowohl das interne Koordinatensystem mittels Koordinatentransformation um xi0 und yi0 verschoben, als auch der Maßstab M bestimmt werden ().

()
Formel 13


Rotation mit Hilfe der Matrix-Befehle

Unverzichtbar sind Befehle, die die Drehung eines Objektes gestatten. Im Beispiel des Sonnensystems liegt ein solcher Fall vor. Während hier die Anwendung der trigonometrischen Funktionen für die Darstellung der kreisenden Planeten bzw. Kometen schon ausreichen würde, wäre die Darstellung von gedrehten Images oder nichtsymmetrischer Objekten gänzlich unmöglich! Hier leisten die Matrix-Befehle unverzichtbare Dienste!

Im folgenden wollen wir beispielhaft am Sonnensystem die Anwendung der Matrix-Befehle verfolgen (). Das Szenarium ist einigermaßen anspruchsvoll, denn nicht nur dreht sich die Erde um die Sonne, es dreht sich auch noch der Mond um die Erde und gemeinsam mit dieser um die Sonne!

Weg-Geschwindigkeit-Beschleunigung
Abb. Drehung von Objekten

Entsprechend sind die folgenden Schritte erforderlich:
  1. zunächst wird das Koordinatensystem aus seiner natürlichen Position (0,0) in den Mittelpunkt der Sonne (nicht dargestellt) verschoben. Die Koordinaten der Sonne fallen mit den Koordinaten xi0, yi0, die den Nullpunkt des kartesischen Koordinatensystems bestimmen, überein. Dazu muss mit einem pushMatrix() bzw. push() das bisherige Koordinatensystem gesichert und mit einem translate(xi0, xi0) die Verschiebung vorgenommen werden.

  2. dieser Schritt befasst sich nun mit der Positionierung der Erde. Da sich die Erde um die Sonne drehen soll, muss es eine Drehbewegung um den Winkel φErde = ωErde ·t geben, der die zeitliche Änderung der Drehung fixiert. Mit diesem Winkel wird ein rotate(φErde) des im 1. Schritt verschobenen Koordinatensystems ausgeführt. Weiterhin muss noch eine weitere Verschiebung um den Erdbahnradius erfolgen, damit die Erde wirklich im Abstand von RErde um die Sonne kreist. Die Erde selbst wird vereinfacht durch eine hellblau gefüllte ellipse() dargestellt. Sie wird auf den Nullpunkt des aktuellen Koordinatensystems gesetzt: ellipse(0, 0, ØErde, ØErde).

  3. jetzt ist der Mond an der Reihe. Das Koordinatensystem des Mondes bewegt sich zusätzlich zum Koordinatensystem der Erde, darum muss dieses auch durch ein pushMatrix() bzw. push() gesichert werden. Da sich der Mond um die Erde drehen soll, muss es eine Drehbewegung um den Winkel φMond = ωMond ·t für die Mondposition geben. Mit diesem Winkel wird ein weiteres rotate(φMond) des im 2. Schritt verschobenen Koordinatensystems ausgeführt. Die erforderliche Verschiebung um den Mondbahnradius kann in dem Befehl zur Darstellung des Mondes (ellipse(0, 0, ØMond, ØMond)) übernommen werden, da keine weiteren Objekte um den Mond kreisen.

  4. Am Ende der Darstellung des vollständigen Erde-Mond-Systems müssen die gesicherten Koordinatensysteme mit einem zweifachen popMatrix() bzw. pop() rekonstruiert werden.
Der Programmauszug ) zeigt die programmtechnische Umsetzung:



Abb. Programmauszug Anwendung rotate() in Verbindung mit translate()

Eine ausführliche Besprechung des Programms findest Du im Abschnitt KEPLERsche Gesetze im 9. Kapitel.