Ich habe einige Modelle, die ich mithilfe von Quaternionen auf normale Weise drehen möchte, außer dass ich sie nicht um den Ursprung drehen möchte, sondern leicht versetzen möchte. Ich weiß, dass Sie im 3D-Raum nicht sagen, dass Sie sich um einen Punkt drehen. Sie sagen, Sie drehen sich um eine Achse. Ich stelle es mir also so vor, als würde es sich um einen Vektor drehen, dessen Schwanz nicht am lokalen Ursprung positioniert ist.
Alle affinen Transformationen in meiner Rendering- / Physik-Engine werden mithilfe von SQT (Maßstab, Quaternion, Übersetzung; eine Idee aus dem Buch Game Engine Architecture ) gespeichert . Daher erstelle ich aus diesen Komponenten für jeden Frame eine Matrix und übergebe sie an den Vertex-Shader. In diesem System wird zuerst die Translation, dann die Skalierung und dann die Rotation angewendet.
In einem bestimmten Fall muss ich ein Objekt im Weltraum verschieben, skalieren und um einen Scheitel drehen, der nicht am lokalen Ursprung des Objekts zentriert ist.
Frage: Wie kann ich unter Berücksichtigung der oben beschriebenen Einschränkungen meines aktuellen Systems eine lokale Rotation erzielen, die um einen anderen Punkt als den Ursprung zentriert ist? Automatisches Upvote für alle, die beschreiben können, wie dies auch nur mit Matrizen gemacht wird :)
quelle
Antworten:
Zusamenfassend
Sie müssen nur T in Ihrem SQT-Formular ändern.
Ersetzen Sie den Translationsvektor
v
mitv' = v-invscale(p-invrotate(p))
demv
die anfängliche Translationsvektor,p
ist der Punkt , um die Sie die Rotation stattfinden soll, undinvrotate
undinvscale
sind die Umkehrungen Ihrer Drehung und Skalierung.Schnelle Demonstration
Sei
p
der Punkt, um den Sie die Drehung anwendenr
. Seien Sies
Ihre Skalierungsparameter undv
Ihr Übersetzungsvektor. Die endgültige Matrixtransformation findetT(p)R(r)T(-p)S(s)T(v)
stattR(r)S(s)T(v)
.Was Sie wollen, sind neue Transformationsparameter
v'
,r'
unds'
so, dass die endgültige Matrixtransformation istR(r')S(s')T(v')
und wir haben:Verhalten im Unendlichen zeigt an, dass sich Rotationsparameter und Skalierungsparameter nicht ändern können (dies könnte demonstriert werden). Wir haben also
r = r'
unds = s'
. Der einzige fehlende Parameter ist daherv'
Ihr neuer Übersetzungsvektor:Wenn diese Matrizen gleich sind, sind ihre Umkehrungen gleich:
Dies gilt insbesondere für die Herkunft
O
:Skalieren und Drehen des Ursprungs ergibt den Ursprung, womit erhalten Sie:
v'
ist der neue Übersetzungsvektor, nach dem Sie suchen, um Ihre Transformation in SQT-Form zu speichern. Es ist wahrscheinlich möglich, die Berechnung zu vereinfachen; Zumindest aber wird der benötigte Speicherplatz nicht erhöht.quelle
Alle kanonischen Rotationsformeln, die zum Ableiten Ihrer Rotationsmatrizen verwendet werden, dienen der Rotation um den Ursprung. Wenn Sie diese Drehung stattdessen um einen bestimmten Punkt anwenden möchten, müssen Sie zuerst den Ursprung versetzen oder das Objekt entsprechend so verschieben, dass sich der Punkt, um den Sie drehen möchten, am Ursprung befindet.
Betrachten Sie zuerst den 2D-Fall, da er einfacher ist und die Technik skaliert. Wenn Sie einen Würfel der Breite 2 auf dem Ursprung zentriert hätten und ihn um 45 Grad um seinen Mittelpunkt drehen möchten, wäre dies eine triviale Anwendung der 2D-Rotationsmatrix .
Wenn Sie es stattdessen um die rechte obere Ecke (befindet sich bei
1,1
) drehen möchten, müssen Sie es zuerst so übersetzen, dass sich die Ecke am Ursprung befindet. Dies kann mit einer Übersetzung von erreicht werden-1,-1
. Anschließend können Sie das Objekt wie zuvor drehen, müssen dies jedoch durch Zurückübersetzen (von1,1
) nachholen . Um also im Allgemeinen die RotationsmatrixR
für eine Rotationr
um einen Punkt zu erhalten, gehenP
Sie wie folgt vor:wo
translate
undrotate
sind die kanonischen Translations- / Rotationsmatrizen. Dies skaliert trivial auf 3D, mit der Ausnahme, dass Sie der Rotation auch eine Achse zuweisen müssen - Sie könnten einfach immer die kanonischen Rotationsmatrizen für die X-, Y- oder Z-Achse auswählen, aber das wäre langweilig. Sie möchten die willkürliche Achsenwinkel-Rotationsmatrix verwenden . Dein FinaleR
in 3D ist also:Dabei
a
steht ein Einheitsvektor für die Rotationsachse undP
ist jetzt ein 3D-Punkt im Modellraum, der den Rotationspunkt darstellt.Quaternionen können zufällig in und aus Matrixdarstellungen konvertiert werden , sodass Sie Ihre Verkettung auf diese Weise durchführen können, falls Sie dies wünschen. Oder Sie können einfach alles als Matrizen belassen (Quaternionen haben einige nette Vorteile, wie zum Beispiel eine einfachere Interpolation, aber ob Sie das brauchen oder nicht, liegt bei Ihnen).
Ebenfalls:
Streng genommen können Vektoren zur Darstellung von Positionen verwendet werden, indem sie als Verschiebungen von einem Ursprung betrachtet werden. Vektoren haben selbst keine Positionen, daher ist es etwas ungewöhnlich, eine Position als solche zu visualisieren.
quelle