Ich habe einen Vector3, der für jede Achse einen Euler-Winkel hat.
Wenn ich eine Rotationsmatrix erstellen möchte, verwende ich normalerweise Funktionen wie D3DXMatrixRotationX, indem ich den entsprechenden Winkel von meinem Rotationsvektor oben übergebe und die Matrizen (ZXY) multipliziere, um die gesamte Rotationsmatrix zu erstellen, die zur Bildung der vollständigen Objekttransformationsmatrix verwendet wird.
Diese Methode erzeugt jedoch eine Reihe von Rotationen im Objektraum. Das heißt, durch Übergabe eines Vektors von (90, 0, 90) an meine Methode wird effektiv eine Drehung im Weltraum von (90, 90, 0) erzeugt.
Gibt es eine Möglichkeit, sicherzustellen, dass jede Komponente meines Rotationsvektors zu einer Rotation um die jeweiligen Achsen im Weltraum führt?
BEARBEITEN:
Dies ist eine Animation dessen, was gerade passiert - ich möchte eine Möglichkeit, um die blauen Achsen zu drehen, nicht um die roten.
EDIT 2:
Nur zur Erinnerung: Ich suche keine Lösung mit Euler-Winkeln, sondern nur eine Möglichkeit, eine Transformation von Mehrfachrotationen um die Weltachsen darzustellen.
quelle
Antworten:
Basierend auf Ihren Kommentaren scheint es, dass Sie die Ausrichtung des Objekts als Satz von Euler-Winkeln speichern und die Winkel beim Drehen des Objekts in / dekrementieren. Das heißt, Sie haben so etwas wie diesen Pseudocode:
Wie Charles Beattie bemerkt , funktioniert dies nicht wie erwartet, da Rotationen nicht pendeln, es sei denn, der Spieler dreht das Objekt in derselben Reihenfolge, in der er
eulerAnglesToMatrix()
die Rotationen anwendet.Beachten Sie insbesondere die folgende Abfolge von Drehungen:
In der naiven Euler-Winkeldarstellung, wie im obigen Pseudocode implementiert, heben sich diese Rotationen auf und das Objekt kehrt in seine ursprüngliche Ausrichtung zurück. In der realen Welt passiert das nicht - wenn du mir nicht glaubst, nimm einen sechsseitigen Würfel oder einen Zauberwürfel, lass x = y = 90 ° und probiere es selbst aus!
Wie Sie in Ihrer eigenen Antwort bemerken , besteht die Lösung darin, die Ausrichtung des Objekts als Rotationsmatrix (oder Quaternion) zu speichern und diese Matrix basierend auf Benutzereingaben zu aktualisieren. Das heißt, anstelle des obigen Pseudocodes würden Sie Folgendes tun:
(Technisch gesehen , da jede Rotationsmatrix oder Quaternion kann als ein Satz von Euler - Winkeln dargestellt werden, es ist möglich , sie zu verwenden , um die Orientierung des Objekts zu speichern. Aber die physikalisch korrekte Regel zwei aufeinanderfolgende Drehungen zu kombinieren, die jeweils dargestellt als Euler - Winkel, Die Umwandlung in eine einzelne Umdrehung ist ziemlich kompliziert und läuft im Wesentlichen darauf hinaus, die Umdrehungen in Matrizen / Quaternionen umzuwandeln, sie zu multiplizieren und das Ergebnis dann wieder in Euler-Winkel umzuwandeln.
quelle
Das Problem bei Rotationen ist, dass die meisten Leute es in Euler-Winkeln sehen, da sie leicht zu verstehen sind.
Die meisten Menschen vergessen jedoch den Punkt, dass Euler-Winkel drei aufeinanderfolgende Winkel sind . Das bedeutet, dass die Drehung um die erste Achse die nächste Drehung relativ zur ersten ursprünglichen Drehung bewirkt. Daher können Sie einen Vektor nicht unabhängig voneinander mit Euler-Winkeln um jede der drei Achsen drehen.
Dies wird direkt in Matrizen übersetzt, wenn Sie zwei Matrizen multiplizieren. Sie können sich diese Multiplikation als Transformation einer Matrix in den Raum der anderen Matrix vorstellen.
Dies soll mit 3 aufeinanderfolgenden Rotationen geschehen, auch wenn Quaternionen verwendet werden.
Ich möchte die Tatsache betonen, dass Quaternionen keine Lösung für Gimble Lock sind. Tatsächlich passiert Gimble Lock immer, wenn Sie Euler-Winkel mit Quaternionen dargestellt haben. Das Problem ist nicht die Darstellung, das Problem sind die 3 aufeinander folgenden Schritte.
Die Lösung?
Die Lösung für das unabhängige Drehen eines Vektors um 3 Achsen besteht darin , ihn in eine einzige Achse und einen einzigen Winkel zu kombinieren. Auf diese Weise können Sie den Schritt beseitigen, bei dem Sie eine sequentielle Multiplikation durchführen müssen. Dies führt effektiv zu:
Meine Rotationsmatrix repräsentiert das Ergebnis der Rotation um X und Y und Z.
eher als die Euler - Interpretation von
Meine Rotationsmatrix repräsentiert die Rotation um X, Y und Z.
Um dies zu verdeutlichen, zitiere ich aus Wikipedia Eulers Rotationssatz:
Beachten Sie, dass das Multiplizieren von 3 Matrizen immer 3 aufeinanderfolgende Rotationen darstellt.
Um nun Rotationen um 3 Achsen zu kombinieren, müssen Sie eine einzelne Achse und einzelne Winkel ermitteln, die die Rotation um X, Y, Z darstellen. Mit anderen Worten, Sie müssen eine Achsen- / Winkel- oder Quaternionendarstellung verwenden, um die sequentiellen Rotationen zu beseitigen.
Dies erfolgt normalerweise, indem Sie mit einer anfänglichen Ausrichtung (Ausrichtung kann als Achsenwinkel betrachtet werden) beginnen, die normalerweise als Quaternion oder Achsenwinkel dargestellt wird, und diese Ausrichtung dann ändern, um Ihre Zielausrichtung darzustellen. Sie beginnen beispielsweise mit dem Identitäts-Quaterion und drehen dann um den Unterschied, um die Zielausrichtung zu erreichen. Auf diese Weise verlieren Sie keinen Freiheitsgrad.
quelle
Das Umschalten einer Rotationskombination vom Objektraum in den Weltraum ist trivial: Sie müssen lediglich die Reihenfolge umkehren, in der die Rotationen angewendet werden.
In Ihrem Fall müssen
Z × X × Y
Sie nur berechnen , anstatt Matrizen zu multiplizierenY × X × Z
.Ein Grund dafür ist auf Wikipedia zu finden: Umrechnung zwischen intrinsischer und extrinsischer Rotation .
quelle
Z
(Objektraum), dann 50 Grad umX
(Objektraum) und dann 45 Grad umY
(Objektraum). Dies entspricht einer Drehung um 45 GradY
( Weltraum ), dann um 50 GradX
( Weltraum ) und dann um 50 GradZ
( Weltraum ).Ich werde meine Lösung als Antwort bereitstellen, bis jemand erklären kann, warum dies funktioniert.
Bei jedem Rendern habe ich meine Quaternion mit den in meinem Rotationsvektor gespeicherten Winkeln neu erstellt und die Quaternion dann auf meine endgültige Transformation angewendet.
Um es jedoch um die Weltachsen zu halten, musste ich das Quaternion über alle Frames hinweg beibehalten und Objekte nur mit einem Winkelunterschied drehen, d. H.
(Ausführlich für die Lesbarkeit)
Ich glaube, dsilva.vinicius hat versucht, an diesen Punkt zu gelangen.
quelle
Sie müssen die Reihenfolge der Rotationen speichern.
Speichern Sie Ihre aktuelle Rotationsmatrix und multiplizieren Sie jede Rotation vorab.
quelle
Zusätzlich zu @ concept3d answer können Sie 3 extrinsische Rotationsmatrizen verwenden, um sich in Weltkoordinaten um die Achse zu drehen. Zitat aus Wikipedia :
Sie müssen also die Reihenfolge der Rotationen im Verhältnis zu dem, was Sie mit intrinsischen (oder lokalen) Rotationen tun würden, umkehren. @Syntac hat nach einer zxy-Rotation gefragt, daher sollten wir eine extrinsische yxz-Rotation durchführen, um das gleiche Ergebnis zu erzielen. Der Code ist unten:
Erklärung der Matrixwerte hier .
Dieser Code ist didaktisch und nicht optimal, da Sie mehrere D3DXMATRIX-Matrizen wiederverwenden können.
quelle