Bisher haben wir die Impulsauflösung, die Kernarchitektur und Reibung behandelt. In diesem letzten Tutorial dieser Serie gehen wir auf ein sehr interessantes Thema ein: Orientierung.
In diesem Artikel werden die folgenden Themen behandelt:
Ich habe dringend empfohlen, die drei vorhergehenden Artikel der Serie vorzulesen, bevor ich mich mit diesem beschäftige. Viele der wichtigsten Informationen in den vorherigen Artikeln sind Voraussetzungen für den Rest dieses Artikels.
Ich habe ein kleines Beispielmodul in C ++ erstellt. Ich empfehle Ihnen, während der gesamten Lektüre dieses Artikels den Quellcode zu durchsuchen und darauf zu verweisen, da viele praktische Implementierungsdetails nicht in den Artikel selbst passen konnten.
Dieses GitHub-Repo enthält die Beispiel-Engine selbst sowie ein Visual Studio 2010-Projekt. Mit GitHub können Sie die Quelle anzeigen, ohne die Quelle selbst herunterladen zu müssen.
zusammenhängende PostsDie Mathematik mit Drehungen in 2D ist recht einfach, obwohl zur Beherrschung des Themas in einer Physik-Engine etwas Wertvolles erforderlich ist. Newtons zweites Gesetz besagt:
\ [Gleichung \: 1: \\
F = ma \]
Es gibt eine ähnliche Gleichung, die insbesondere die Winkelkraft und die Winkelbeschleunigung betrifft. Bevor diese Gleichungen gezeigt werden können, ist jedoch eine kurze Beschreibung des Kreuzprodukts in 2D erforderlich.
Das Kreuzprodukt in 3D ist eine bekannte Operation. Das Kreuzprodukt in 2D kann jedoch recht verwirrend sein, da es keine wirklich geometrische Interpretation gibt.
Das 2D-Kreuzprodukt gibt im Gegensatz zur 3D-Version keinen Vektor zurück, sondern einen Skalar. Dieser Skalarwert stellt tatsächlich die Größe des orthogonalen Vektors entlang der z-Achse dar, wenn das Kreuzprodukt tatsächlich in 3D ausgeführt werden sollte. In gewisser Weise ist das 2D-Kreuzprodukt nur eine vereinfachte Version des 3D-Kreuzprodukts, da es eine Erweiterung der 3D-Vektor-Mathematik ist.
Wenn dies verwirrend ist, machen Sie sich keine Sorgen: Ein gründliches Verständnis des 2D-Kreuzprodukts ist nicht unbedingt erforderlich. Sie müssen nur genau wissen, wie die Operation ausgeführt wird, und wissen, dass die Reihenfolge der Operationen wichtig ist: \ (a \ times b \) ist nicht dasselbe wie \ (b \ times a \). In diesem Artikel wird das Kreuzprodukt intensiv genutzt, um die Winkelgeschwindigkeit in eine lineare Geschwindigkeit umzuwandeln.
Wissen Wie Es ist jedoch sehr wichtig, das Kreuzprodukt in 2D auszuführen. Zwei Vektoren können gekreuzt werden, ein Skalar kann mit einem Vektor gekreuzt werden und ein Vektor kann mit einem Skalar gekreuzt werden. Hier sind die Operationen:
// Zwei gekreuzte Vektoren liefern einen skalaren Float CrossProduct (const Vec2 & a, const Vec2 & b) return a.x * b.y - a.y * b.x; // Exotischere (aber notwendige) Formen des Kreuzprodukts // mit einem Vektor a und Skalar s, wobei beide einen Vektor liefern. Vec2 CrossProduct (const Vec2 & a, float s) return Vec2 (s * ay, -s * ax) ); Vec2 CrossProduct (float s, const Vec2 & a) return Vec2 (-s * a.y, s * a.x);
Wie wir alle aus den vorangegangenen Artikeln wissen sollten, stellt diese Gleichung eine Beziehung zwischen der auf einen Körper mit der Körpermasse wirkenden Kraft und der Beschleunigung dar. Es gibt ein Analog für Rotation:
\ [Gleichung \: 2: \\
T = r \: \ times \: \ omega \]
\ (T \) steht für Drehmoment. Drehmoment ist Rotationskraft.
\ (r \) ist ein Vektor vom Massenmittelpunkt (COM) zu einem bestimmten Punkt auf einem Objekt. Man kann sich vorstellen, dass \ (r \) sich auf einen "Radius" von COM zu einem Punkt bezieht. Für jeden einzelnen eindeutigen Punkt in einem Objekt muss in Gleichung 2 ein anderer \ (r \) -Wert dargestellt werden.
\ (\ omega \) wird "omega" genannt und bezieht sich auf die Rotationsgeschwindigkeit. Diese Beziehung wird verwendet, um die Winkelgeschwindigkeit eines starren Körpers zu integrieren.
Es ist wichtig zu verstehen, dass die lineare Geschwindigkeit die Geschwindigkeit der COM eines starren Körpers ist. Im vorigen Artikel hatten alle Objekte keine Rotationskomponenten, daher war die Lineargeschwindigkeit der COM für alle Punkte eines Körpers gleich. Wenn die Orientierung eingeführt wird, drehen sich Punkte, die weiter vom COM entfernt sind, schneller als in der Nähe des COM. Dies bedeutet, dass wir eine neue Gleichung benötigen, um die Geschwindigkeit eines Punkts auf einem Körper zu ermitteln, da sich Körper jetzt gleichzeitig drehen und verschieben können.
Verwenden Sie die folgende Gleichung, um die Beziehung zwischen einem Punkt auf einem Körper und der Geschwindigkeit dieses Punktes zu verstehen:
\ [Gleichung \: 3: \\
\ omega = r \: \ times v \]
\ (v \) steht für die Lineargeschwindigkeit. Um die lineare Geschwindigkeit in die Winkelgeschwindigkeit umzuwandeln, kreuzen Sie den \ (r \) -Radius mit \ (v \)..
In ähnlicher Weise können wir Gleichung 3 neu anordnen, um eine andere Version zu bilden:
\ [Gleichung \: 4: \\
v = \ omega \: \ times r \]
Die Gleichungen aus dem letzten Abschnitt sind nur dann recht leistungsfähig, wenn starre Körper eine gleichmäßige Dichte haben. Die ungleichmäßige Dichte macht die Berechnungen, die bei der Berechnung von Dingen mit einbezogen werden, zu Rotation und Verhalten eines starren Körpers viel zu kompliziert. Wenn sich der Punkt, der einen starren Körper darstellt, nicht in der COM befindet, werden die Berechnungen in Bezug auf \ (r \) völlig falsch.
In zwei Dimensionen dreht sich ein Objekt um die imaginäre Z-Achse. Diese Drehung kann ziemlich schwierig sein, abhängig davon, wie viel Masse ein Objekt hat und wie weit die Masse des Objekts von der COM entfernt ist. Ein Kreis mit einer Masse, die einer langen, dünnen Stange entspricht, lässt sich leichter drehen als die Stange. Dieser "Schwierigkeitsgrad beim Drehen" kann als Trägheitsmoment eines Objekts betrachtet werden.
Trägheit ist gewissermaßen die Rotationsmasse eines Objekts. Je mehr Trägheit etwas hat, desto schwieriger ist es, dass es sich dreht.
Wenn man dies weiß, könnte man die Trägheit eines Objekts im Körper als das gleiche Format wie die Masse speichern. Es wäre ratsam, auch die Umkehrung dieses Trägheitswertes zu speichern, wobei darauf zu achten ist, dass keine Division durch Null durchgeführt wird. Weitere Informationen zu Masse und inverser Masse finden Sie in den vorherigen Artikeln dieser Serie.
Für jeden starren Körper sind einige weitere Felder erforderlich, um Rotationsinformationen zu speichern. Hier ist ein schnelles Beispiel für eine Struktur, die zusätzliche Daten enthält:
struct RigidBody Shape * shape // Lineare Komponenten Vec2-Position Vec2 Geschwindigkeitsschwimmerbeschleunigung // Winkelkomponenten Schwebekörperorientierung // Radiant SchwimmerkegelVelocity-Schwimmermoment;
Die Integration von Winkelgeschwindigkeit und Orientierung eines Körpers ist der Integration von Geschwindigkeit und Beschleunigung sehr ähnlich. Hier ein kurzes Codebeispiel, um zu zeigen, wie es gemacht wird (Hinweis: Einzelheiten zur Integration wurden in einem vorherigen Artikel behandelt):
const Vec2 Schwerkraft (0, -10,0f) Geschwindigkeit + = Kraft * (1,0f / Masse + Schwerkraft) * dt angleVelocity + = Drehmoment * (1.0f / momentOfInertia) * dt Position + = Geschwindigkeit * dt orient + + anglevelocity * dt
Mit der geringen Menge an Informationen, die bisher präsentiert wurden, sollten Sie verschiedene Dinge auf dem Bildschirm problemlos drehen können. Mit nur wenigen Codezeilen kann etwas sehr Eindrucksvolles konstruiert werden, vielleicht indem man eine Form in die Luft wirft, während sie sich um die COM dreht, während die Schwerkraft sie nach unten zieht, um einen bogenförmigen Bewegungspfad zu bilden.
Mat22
Die Orientierung sollte, wie oben gezeigt, als einzelner Radiantwert gespeichert werden, obwohl die Verwendung einer kleinen Rotationsmatrix für bestimmte Formen oft die bessere Wahl sein kann.
Ein gutes Beispiel ist die Oriented Bounding Box (OBB). Die OBB besteht aus einer Breiten- und Höhenausdehnung, die beide durch Vektoren dargestellt werden können. Diese beiden Ausdehnungsvektoren können dann durch eine Zwei-mal-Zwei-Rotationsmatrix gedreht werden, um die Achsen eines OBB darzustellen.
Ich schlage die Schaffung eines vor Mat22
Matrix-Klasse, die zu der von Ihnen verwendeten mathematischen Bibliothek hinzugefügt werden soll. Ich selbst verwende eine kleine benutzerdefinierte Mathematikbibliothek, die in der Open Source-Demo enthalten ist. Hier ist ein Beispiel, wie ein solches Objekt aussehen kann:
struct Mat22 union struct float m00, m01 float m10, m11; ; struct Vec2 xCol; Vec2 yCol; ; ; ;
Einige nützliche Operationen umfassen: Konstruktion aus Winkel, Konstruktion aus Spaltenvektoren, transponieren, mit multiplizieren Vec2
, multiplizieren Sie mit einem anderen Mat22
, absoluter Wert.
Die letzte nützliche Funktion besteht darin, entweder die x
oder y
Spalte aus einem Vektor. Die Spaltenfunktion würde ungefähr so aussehen:
Mat22 m (PI / 2.0f); Vec2 r = m.ColX (); // die x-Achsenspalte abrufen
Diese Technik ist nützlich, um einen Einheitsvektor entlang der Drehachse abzurufen, entweder die x
oder y
Achse. Zusätzlich kann eine Zwei-mal-Zwei-Matrix aus zwei orthogonalen Einheitsvektoren konstruiert werden, da jeder Vektor direkt in die Zeilen eingefügt werden kann. Obwohl diese Konstruktionsmethode für 2D-Physik-Engines etwas ungewöhnlich ist, kann es dennoch nützlich sein, zu verstehen, wie Rotationen und Matrizen im Allgemeinen funktionieren.
Dieser Konstruktor könnte ungefähr so aussehen:
Mat22 :: Mat22 (const Vec2 & x, const Vec2 & y) m00 = x.x; m01 = x.y; m01 = y.x; m11 = y.y; // oder Mat22 :: Mat22 (const Vec2 & x, const Vec2 & y) xCol = x; yCol = y;
Da die wichtigste Operation einer Rotationsmatrix darin besteht, Rotationen basierend auf einem Winkel durchzuführen, ist es wichtig, eine Matrix aus einem Winkel konstruieren und einen Vektor mit dieser Matrix multiplizieren zu können (den Vektor gegen den Uhrzeigersinn um den Winkel zu drehen) Matrix wurde konstruiert mit):
Mat2 (echte Radiant) real c = std :: cos (Radiant); real s = std :: sin (Bogenmaß); m00 = c; m01 = -s; m10 = s; m11 = c; // Rotiere einen Vektor const Vec2-Operator * (const Vec2 & rhs) const return Vec2 (m00 * rhs.x + m01 * rhs.y, m10 * rhs.x + m11 * rhs.y);
Der Kürze halber werde ich nicht ableiten, warum die Rotationsmatrix gegen den Uhrzeigersinn folgende Form hat:
a = Winkel cos (a), -sin (a) sin (a), cos (a)
Es ist jedoch wichtig zu wissen, dass dies die Form der Rotationsmatrix ist. Weitere Informationen zu Rotationsmatrizen finden Sie auf der Wikipedia-Seite.
zusammenhängende PostsEs ist wichtig, den Unterschied zwischen Modell und Weltraum zu verstehen. Der Modellraum ist das lokale Koordinatensystem einer Physikform. Der Ursprung befindet sich am COM, und die Ausrichtung des Koordinatensystems ist an den Achsen der Form selbst ausgerichtet.
Um eine Form in den Weltraum zu verwandeln, muss sie gedreht und verschoben werden. Die Drehung muss zuerst erfolgen, da immer um den Ursprung gedreht wird. Da sich das Objekt im Modellbereich befindet (Ursprung bei COM), wird die Drehung um die COM der Form gedreht. Rotation würde mit einem auftreten Mat22
Matrix. Im Beispielcode haben Orientierungsmatrizen den Namen u
.
Nachdem die Drehung ausgeführt wurde, kann das Objekt durch Vektoraddition in seine Position in der Welt verschoben werden.
Sobald sich ein Objekt im Weltraum befindet, kann es mit inversen Transformationen in den Modellraum eines völlig anderen Objekts übersetzt werden. Dabei wird die umgekehrte Rotation gefolgt von der inversen Translation verwendet. Dies ist, wie viel Mathematik bei der Kollisionserkennung vereinfacht wird!
Inverse Transformation (von links nach rechts) vom Weltraum in den Modellraum des roten Polygons.Wie in dem obigen Bild zu sehen ist, kann, wenn die inverse Transformation des roten Objekts sowohl auf das rote als auch das blaue Polygone angewendet wird, ein Kollisionserkennungstest auf die Form eines AABB-vs-OBB-Tests reduziert werden, anstatt eine komplexe Mathematik zwischen zwei zu berechnen orientierte Formen.
In einem Großteil des Beispielquellcodes werden Scheitelpunkte aus verschiedenen Gründen ständig vom Modell in die Welt und zurück in das Modell umgewandelt. Sie sollten ein klares Verständnis davon haben, was dies bedeutet, um den Code für die Erkennung von Beispielkollisionen zu verstehen.
In diesem Abschnitt werde ich kurze Umrisse von Polygon- und Kreiskollisionen vorstellen. Weitere Einzelheiten zur Implementierung finden Sie im Beispielquellcode.
Beginnen wir mit der komplexesten Kollisionserkennungsroutine in dieser gesamten Artikelserie. Die Idee, nach einer Kollision zwischen zwei Polygonen zu suchen, wird am besten (meiner Meinung nach) mit dem Trennachsensatz (SAT) durchgeführt..
Anstatt die Ausdehnungen jedes Polygons aufeinander zu projizieren, gibt es jedoch eine etwas neuere und effizientere Methode, wie von Dirk Gregorius in seiner GDC-Lecture 2013 beschrieben (Folien hier kostenlos erhältlich)..
Das erste, was gelernt werden muss, ist das Konzept der Stützpunkte.
Der Stützpunkt eines Polygons ist der Scheitelpunkt, der in einer bestimmten Richtung am weitesten entfernt ist. Wenn zwei Scheitelpunkte gleiche Abstände in der angegebenen Richtung haben, ist einer davon akzeptabel.
Um einen Stützpunkt zu berechnen, muss das Punktprodukt verwendet werden, um eine vorzeichenbehaftete Entfernung entlang einer gegebenen Richtung zu finden. Da dies sehr einfach ist, zeige ich in diesem Artikel ein kurzes Beispiel:
// Der Extrempunkt entlang einer Richtung innerhalb eines Polygons Vec2 GetSupport (const Vec2 & dir) real bestProjection = -FLT_MAX; Vec2 bestVertex; für (uint32i = 0; i < m_vertexCount; ++i) Vec2 v = m_vertices[i]; real projection = Dot( v, dir ); if(projection > bestProjection) bestVertex = v; bestProjection = Projektion; return bestVertex;
Das Punktprodukt wird auf jedem Scheitelpunkt verwendet. Das Punktprodukt repräsentiert einen vorzeichenbehafteten Abstand in einer bestimmten Richtung, sodass der Scheitelpunkt mit dem größten projizierten Abstand der zurückzukehrende Scheitelpunkt ist. Diese Operation wird im Modellbereich des angegebenen Polygons innerhalb der Muster-Engine ausgeführt.
Mit dem Konzept der Stützpunkte kann eine Suche nach der Trennachse zwischen zwei Polygonen (Polygon A und Polygon B) durchgeführt werden. Die Idee dieser Suche besteht darin, alle Flächen des Polygons A entlang zu schleifen und den Stützpunkt in der negativen Normalen dieser Fläche zu finden.
In der obigen Abbildung werden zwei Stützpunkte angezeigt: einer für jedes Objekt. Die blaue Normale würde dem Stützpunkt des anderen Polygons entsprechen, da der Scheitelpunkt in der entgegengesetzten Richtung der blauen Normalen am weitesten entfernt ist. In ähnlicher Weise wird die rote Normale verwendet, um den Stützpunkt am Ende des roten Pfeils zu finden.
Die Entfernung von jedem Stützpunkt zur aktuellen Fläche wäre die vorzeichenbehaftete Durchdringung. Durch das Speichern der größten Entfernung kann eine mögliche minimale Durchdringungsachse aufgezeichnet werden.
Hier ist eine Beispielfunktion aus dem Beispielquellcode, die mithilfe von die mögliche Achse der minimalen Penetration ermittelt GetSupport
Funktion:
real FindAxisLeastPenetration (uint32 * faceIndex, PolygonShape * A, PolygonShape * B) real bestDistance = -FLT_MAX; uint32 bestIndex; für (uint32i = 0; i < A->m_vertexCount; ++ i) // Ein normales Gesicht von A Vec2 abrufen n = A-> m_normals [i]; // Unterstützungspunkt von B zusammen mit -n Vec2 abrufen s = B-> GetSupport (-n); // Scheitelpunkt auf Gesicht von A abrufen und in // Bs Modellbereich umwandeln Vec2 v = A-> m_vertices [i]; // Berechne die Eindringentfernung (in B's Modellraum) real d = Dot (n, s - v); // Größte Entfernung speichern, wenn (d> bestDistance) bestDistance = d; bestIndex = i; * faceIndex = bestIndex; bestDistance zurückgeben;
Da diese Funktion die größte Durchdringung zurückgibt, bedeutet die positive Durchdringung, dass sich die beiden Formen nicht überlappen (negative Durchdringung bedeutet keine Trennachse)..
Diese Funktion muss zweimal aufgerufen werden, wobei A- und B-Objekte bei jedem Aufruf umgedreht werden müssen.
Von hier aus müssen die Einfalls- und Referenzfläche identifiziert werden, und die Einfallsfläche muss gegen die Seitenebenen der Referenzfläche geschnitten werden. Dies ist eine eher nicht triviale Operation, obwohl Erin Catto (Schöpfer von Box2D und alle derzeit von Blizzard verwendeten Physik) einige großartige Folien zu diesem Thema ausführlich erstellt hat.
Dieses Abschneiden erzeugt zwei mögliche Kontaktpunkte. Alle Kontaktpunkte hinter der Referenzfläche können als Kontaktpunkte betrachtet werden.
Neben den Folien von Erin Catto wurden für die Beispiel-Engine auch die Clipping-Routinen als Beispiel implementiert.
Die Kollisionsroutine Kreis gegen Polygon ist um einiges einfacher als die Erkennung von Polygon gegen Polygonkollisionen. Zuerst wird die Fläche, die dem Mittelpunkt des Kreises am nächsten kommt, auf ähnliche Weise berechnet wie bei der Verwendung von Stützpunkten aus dem vorherigen Abschnitt: indem Sie jede Flächen-Normale des Polygons durchlaufen und den Abstand vom Mittelpunkt des Kreises zur Fläche ermitteln.
Wenn sich der Mittelpunkt des Kreises hinter dieser engsten Fläche befindet, können spezifische Kontaktinformationen generiert werden und die Routine kann sofort enden.
Nachdem die nächstliegende Fläche identifiziert wurde, wird der Test in einen Liniensegment-Kreis-Test umgewandelt. Ein Liniensegment hat drei interessante Regionen Voronoi-Regionen. Untersuchen Sie das folgende Diagramm:
Voronoi-Regionen eines Liniensegments.Intuitiv können abhängig davon, wo sich der Mittelpunkt des Kreises befindet, verschiedene Kontaktinformationen abgeleitet werden. Stellen Sie sich vor, der Mittelpunkt des Kreises liegt in einem der beiden Scheitelpunkte. Dies bedeutet, dass der Punkt, der dem Mittelpunkt des Kreises am nächsten liegt, ein Kantenscheitelpunkt ist und die richtige Kollisionsnormale ein Vektor von diesem Scheitelpunkt zum Kreismittelpunkt ist.
Wenn sich der Kreis innerhalb des Flächenbereichs befindet, ist der Mittelpunkt des Kreises der Mittelpunkt des Kreises auf das Segment. Die Kollisionsnormalität ist nur die Gesichtsnormale.
Um zu berechnen, in welcher Voronoi-Region sich der Kreis befindet, verwenden wir das Punktprodukt zwischen mehreren Scheitelpunkten. Die Idee ist, ein imaginäres Dreieck zu erstellen und zu testen, ob der Winkel der mit dem Scheitelpunkt des Segments konstruierten Ecke über oder unter 90 Grad liegt. Für jeden Scheitelpunkt des Liniensegments wird ein Dreieck erstellt.
Projizieren eines Vektors vom Kantenscheitelpunkt zum Kreismittelpunkt auf die Kante.Ein Wert von über 90 Grad bedeutet, dass ein Randbereich identifiziert wurde. Wenn keiner der Eckenscheitelwinkel des Dreiecks über 90 Grad liegt, muss der Mittelpunkt des Kreises auf das Segment selbst projiziert werden, um vielfältige Informationen zu generieren. Wie im obigen Bild zu sehen, ist der Voronoi-Bereich, in dem sich der Kreis befindet, bekannt, wenn der Vektor vom Kantenscheitel bis zum mit dem Kantenvektor selbst gepunkteten Kreismittelpunkt negativ ist.
Glücklicherweise kann das Punktprodukt zur Berechnung einer vorzeichenbehafteten Projektion verwendet werden. Dieses Vorzeichen ist negativ, wenn es über 90 Grad liegt, und positiv, wenn es darunter liegt.
Es ist wieder soweit: Wir kehren zum dritten und letzten Mal zu unserem Impulsauflösungscode zurück. Inzwischen sollte es Ihnen völlig angenehm sein, einen eigenen Auflösungscode zu schreiben, der die Auflösungsimpulse zusammen mit den Reibungsimpulsen berechnet und auch eine lineare Projektion durchführen kann, um verbleibende Durchbrüche aufzulösen.
Rotationskomponenten müssen sowohl zur Reibungs- als auch zur Durchdringungsauflösung hinzugefügt werden. Ein Teil der Energie wird in Winkelgeschwindigkeit gebracht.
Hier ist unsere Impulsauflösung, wie wir sie aus dem vorherigen Artikel über Reibung verlassen haben:
\ [Gleichung 5: \\
j = \ frac - (1 + e) ((V ^ A - V ^ B) * t) \ frac 1 Masse ^ A + \ frac 1 Masse ^ B
\]
Wenn wir Rotationskomponenten einwerfen, sieht die endgültige Gleichung folgendermaßen aus:
\ [Gleichung 6: \\
j = \ frac - (1 + e) ((V ^ A - V ^ B) * t) \ frac 1 Masse ^ A + \ frac 1 Masse ^ B + \ frac (r ^ A \ times t) ^ 2 I ^ A + \ frac (r ^ B \ times t) ^ 2 I ^ B
\]
In der obigen Gleichung ist \ (r \) wiederum ein "Radius", wie in einem Vektor vom COM eines Objekts zum Kontaktpunkt. Eine detailliertere Ableitung dieser Gleichung finden Sie auf der Website von Chris Hecker.
Es ist wichtig zu wissen, dass die Geschwindigkeit eines bestimmten Punktes auf einem Objekt folgendermaßen ist:
\ [Gleichung 7: \\
V '= V + \ omega \ times r
\]
Die Anwendung von Impulsen ändert sich geringfügig, um die Rotationsterme zu berücksichtigen:
void Body :: ApplyImpulse (const Vec2 & Impuls, const Vec2 & contactVector) Geschwindigkeit + = 1.0f / Masse * Impuls; angleVelocity + = 1.0f / Trägheit * Kreuz (KontaktVektor, Impuls);
Damit ist der letzte Artikel dieser Serie abgeschlossen. Inzwischen wurden bereits einige Themen behandelt, darunter impulsbasierte Auflösung, vielfältige Erzeugung, Reibung und Orientierung, alles in zwei Dimensionen.
Wenn Sie es soweit geschafft haben, muss ich Ihnen gratulieren! Die Programmierung der Physik-Engine für Spiele ist ein äußerst schwieriger Studienbereich. Ich wünsche allen Lesern viel Glück und bitte weiter unten, um etwas zu kommentieren oder Fragen zu stellen.