Ich bin ein Spieleentwickler und habe keine Mathematik studiert. Ich möchte also nur Quaternions als Werkzeug verwenden. Um mit 3D-Rotation arbeiten zu können, ist es erforderlich, Quaternions (oder Matrizen) zu verwenden. Lassen Sie uns jedoch in dieser Frage bei Quaternions bleiben. Ich denke, dass es für viele Entwickler wichtig ist, sie zu verwenden. Deshalb möchte ich mein Wissen teilen und hoffentlich die Lücken füllen, die ich habe. Jetzt....
So weit ich verstanden habe:
Eine Quaternion kann zwei Dinge beschreiben:
- Die aktuelle Ausrichtung eines 3D-Objekts.
- Die Rotationstransformation, die ein Objekt ausführen könnte. (rotationChange)
Du kannst mit einer Quaternion machen:
Multiplikationen:
Quaternion endOrientation = Quaternion rotationChange * Quaternion currentOrientation;
Zum Beispiel: Mein 3D-Objekt ist um 90 ° nach links gedreht - und meine Drehung, die ich multipliziere, ist eine Drehung um 180 ° nach rechts, am Ende ist mein 3D-Objekt um 90 ° nach rechts gedreht.
Quaternion rotationChange = Quaternion endRotation * Quaternion.Inverse (startRotation);
Hiermit erhalten Sie eine Rotationsänderung, die auf eine andere Ausrichtung angewendet werden kann.
Vector3 endPostion = Quaternion rotationChange * Vector3 currentPosition;
Zum Beispiel: Mein 3D-Objekt ist auf Position (0,0,0) und meine Drehung, die ich multipliziere, ist eine Drehung um 180 ° nach rechts, meine Endposition ist ungefähr (0, -50,0). In dieser Quaternion gibt es eine Achse - und eine Drehung um diese Achse. Sie drehen Ihren Punkt um diese Achse Y Grad.
Vector3 turnedOffsetVector = Quaternion rotationChange * Vector3 currentOffsetVector;
Zum Beispiel: Meine Startrichtung zeigt UP - (0,1,0), und meine Drehung, die ich multipliziere, ist eine Drehung um 180 ° nach rechts, meine Endrichtung zeigt nach unten. (0, -1,0)
Mischen (Lerp und Slerp):
Quaternion currentOrientation = Quaternion.Slerp (startOrientation, endOrientation, interpolator)
Wenn der Interpolator 1 ist: currentOrientation = endOrientation
Wenn der Interpolator 0 ist: currentOrientation = startOrientation
Slerp interpoliert präziser, Lerp interpoliert performanter.
Meine Fragen):
Ist alles, was ich bis jetzt erklärt habe, richtig?
Ist das "alles", was Sie mit Quaternions tun können? (obv. nicht)
Was können Sie sonst noch mit ihnen machen?
Wofür eignen sich das Dot-Produkt und das Cross-Produkt zwischen 2 Quaternionen?
Bearbeiten:
Aktualisierte Frage mit einigen Antworten
quelle
n
unterschiedliche Ausrichtungen (Einstellungen, Posen usw.). Dann können Sie sie mit Gewichten mitteln und so Slerp / Lerp effektiv verallgemeinern. Sie können ein Quaternion auch in einen Rotor umwandeln, was dem Anwenden einer Winkelgeschwindigkeit für einen bestimmten Zeitraum auf einen starren Körper entspricht. Daher können Sie die Winkelgeschwindigkeitsintegration auch mit Quaternionen beschreiben. Sie können auch schätzen, wie unterschiedlich zwei Ausrichtungen sind (berechnen Sie die Länge des Bogens, der von den beiden Quaternionen auf der Hypersphäre gespannt wird).Antworten:
Multiplikation
Zumindest im Hinblick auf die Implementierung von Quaternions durch Unity ist die in der Frage beschriebene Multiplikationsreihenfolge nicht korrekt. Dies ist wichtig, da die 3D-Drehung nicht kommutativ ist .
Wenn ich also ein Objekt drehen möchte, indem ich
rotationChange
von dem ObjektcurrentOrientation
ausgehe, würde ich es folgendermaßen schreiben:(dh Transformationen stapeln sich bis zur linken Seite - genau wie bei der Unity-Matrixkonvention. Die Drehung ganz rechts wird zuerst / am "lokalsten" Ende angewendet.)
Und wenn ich eine Richtung oder einen Versatzvektor um eine Drehung transformieren wollte, würde ich das so schreiben:
(Unity erzeugt einen Kompilierungsfehler, wenn Sie das Gegenteil tun.)
Mischen
In den meisten Fällen kommt man mit Lerping-Rotationen davon. Dies liegt daran, dass der Winkel, der "unter der Haube" in einem Quaternion verwendet wird, halb so groß ist wie der Drehwinkel, wodurch er der linearen Annäherung von Lerp wesentlich näher kommt als so etwas wie eine Matrix (die im Allgemeinen nicht gut funktioniert!). Weitere Erklärungen finden Sie in ca. 40 Minuten in diesem Video .
Der einzige Fall, in dem Sie Slerp wirklich brauchen, ist, wenn Sie im Laufe der Zeit eine konstante Geschwindigkeit benötigen, z. B. das Interpolieren zwischen Keyframes auf einer Animationszeitleiste. In Fällen, in denen es Ihnen nur wichtig ist, dass eine Ausgabe zwischen zwei Eingaben liegt (wie das Mischen von Ebenen einer Animation), eignet sich Lerp normalerweise sehr gut.
Was sonst?
Das Skalarprodukt zweier Einheitsquaternionen gibt den Kosinus des Winkels zwischen ihnen an, sodass Sie das Skalarprodukt als Maß für die Ähnlichkeit verwenden können, wenn Sie Rotationen vergleichen müssen. Dies ist allerdings etwas undurchsichtig, sodass ich für besser lesbaren Code häufig Quaternion.Angle (a, b) verwende, was deutlicher ausdrückt, dass wir Winkel in vertrauten Einheiten (Grad) vergleichen.
Diese Arten von praktischen Methoden, die Unity für Quaternions bereitstellt, sind sehr nützlich. In fast jedem Projekt verwende ich dieses mindestens ein paar Mal :
Dies bildet eine Quaternion, die:
forward
Vektorargument zu zeigenup
Vektorargument zu zeigen, sofern dies angegeben oder(0, 1, 0)
weggelassen wirdDer Grund, warum das "Auf" nur "so nah wie möglich" kommt, ist, dass das System überbestimmt ist. Wenn
forward
wir z + gegenüberstellen, um zwei Freiheitsgrade (dh Gieren und Nicken) zu verbrauchen, bleibt uns nur ein Freiheitsgrad (Rollen).Ich finde ziemlich oft, dass ich etwas mit den entgegengesetzten Genauigkeitseigenschaften möchte: Ich möchte, dass lokales y + genau entlang
up
zeigt und lokales z +forward
mit der verbleibenden Freiheit so nahe wie möglich kommt .Dies ist zum Beispiel der Fall, wenn Sie versuchen, einen kamerarelativen Koordinatenrahmen für die Bewegungseingabe zu erstellen: Ich möchte, dass meine lokale Aufwärtsrichtung senkrecht zum Boden oder zur Normalen der geneigten Oberfläche bleibt, damit meine Eingabe nicht versucht, den Charakter in das Gelände zu tunneln oder schweben sie davon ab.
Dies kann auch der Fall sein, wenn das Turmgehäuse eines Panzers auf ein Ziel gerichtet sein soll, ohne sich beim Zielen nach oben / unten vom Panzerkörper abzuziehen.
Dazu können wir unsere eigene Komfortfunktion aufbauen, die
LookRotation
für das schwere Heben verwendet wird:Hier drehen wir zuerst das lokale y + zu z + und das lokale z + zu y-.
Dann drehen wir das neue z + in unsere Aufwärtsrichtung (so dass das Nettoergebnis lokal y + zeigt direkt entlang
exactUp
) und das neue y + so nah wie möglich an der negierten Vorwärtsrichtung (so dass das Nettoergebnis lokal z + zeigt so nah wie möglich entlang)approximateForward
)Eine andere praktische Bequemlichkeitsmethode
Quaternion.RotateTowards
, die ich oft so benutze:Auf diese Weise können wir
targetRotation
unabhängig von der Framerate mit einer konstanten, steuerbaren Geschwindigkeit näherkommen - wichtig für Rotationen, die das Ergebnis / die Fairness der Spielmechanik beeinflussen (wie das Drehen der Bewegung eines Charakters oder das Einfahren eines Turmes auf dem Spieler). Naives Lerping / Slerping in dieser Situation kann leicht zu Fällen führen, in denen die Bewegung bei hohen Frameraten schneller wird und die Spielbalance beeinträchtigt. (Das heißt nicht, dass diese Methoden falsch sind - es gibt Möglichkeiten, sie korrekt anzuwenden, ohne die Fairness zu ändern. Sie erfordern lediglich Sorgfalt. EsRotateTowards
gibt eine praktische Verknüpfung, die dies für uns erledigt.)quelle
Wo wird das Skalarprodukt verwendet?
In Unity ist einer der häufigsten Benutzer des Skalarprodukts immer dann, wenn Sie über
==
oder prüfen, ob zwei Quaternionen gleich sind!=
. Unity berechnet das Skalarprodukt, um die Ähnlichkeit zu überprüfen, anstatt die internen x-, y-, z- und w-Werte direkt zu vergleichen. Es lohnt sich, dies zu bedenken, da es den Anruf teurer macht, als Sie vielleicht erwarten.Wir verwenden es auch in einem interessanten Anwendungsfall.
Spaß mit Quaternion Dot Produkten - Sphärische Welten und Orbitale
Simulationen ganzer Planeten und sogar ganzer Sonnensysteme werden immer häufiger. Um dies in Echtzeit umzusetzen, benötigen wir auch das Quaternion Dot-Produkt. Viele von ihnen. Das Quaternion-Dot-Produkt ist sehr wenig genutzt, hat aber durchaus seine Verwendungsmöglichkeiten - Schauen wir uns das an!
Erstens müssen wir eine ganze Reihe von Rotationen berücksichtigen:
Kombinieren Sie sie alle zusammen und Sie erhalten eine Menge Komplexität (und eine Menge riesiger Zahlen!). Wenn der Betrachter auf der Oberfläche des Planeten steht, wollen wir nicht, dass sie mit einer verrückten Geschwindigkeit durch unseren Spielweltraum rasen. Wir möchten, dass sie stationär sind und sich irgendwo in der Nähe des Ursprungs befinden. Bewegen Sie das Universum stattdessen um den Spieler.
Wichtig ist, dass wir, damit wir in diesem Szenario in der Lage sind, die Drehung und Neigung des Planeten richtig zu machen, die Stange in der Achse arretieren müssen, damit sie auf dem obigen Bild nur auf- und abschwingen kann (dh aufschwingen, wenn sich der Spieler bewegt) Norden). Hier kommt ein Quaternion Dot-Produkt ins Spiel. Wenn wir hier kein Dot-Produkt verwenden und stattdessen auch nur die Neigung multiplizieren würden, würde dies passieren:
Beachten Sie, wie die Pole unserer umlaufenden "Planeten" immer in Richtung des Sterns geneigt sind. Dies ist nicht das, was in der Realität passiert - die Neigung ist in eine feste Richtung .
Hier eine kurze Zusammenfassung, ohne zu weit vom Thema abzuweichen:
Indem wir nur den Winkel erhalten, lassen wir einen Teil dieser unerwünschten Drehung fallen . Gleichzeitig haben wir eine Längenmessung durchgeführt, die sowohl für die Navigation als auch für das lokale Klima nützlich ist.
* Planeten bestehen aus vielen Gitterzellen . Es werden nur die in der Nähe befindlichen angezeigt.
quelle
dot(a, b) = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w
im Gegensatz zur Quaternion- Zusammensetzung, die wir zum Verketten verwenden würden) funktioniert Rotationen) würde uns helfen, dieses Problem zu lösen. Ich würde mich freuen, wenn Sie dies etwas später erläutern können (ich möchte Sie nicht von Ihrem Slerp fernhalten ... ich meine den Schlaf!)