Dual Quaternion
(Mehr Informationen/weitere Artikel)
Mathematische Hintergründe fehlen. Das ist bisher nur aus Sicht eines Programmierers geschrieben. |
Dual Quaternions (Duale Quaternionen) sind eine Erweiterung der hamiltonschen Quaternionen um die duale Komponente. Geometrisch betrachtet führen duale Quaternionen die Translation ein, während einfache Quaternionen nur Rotation darstellen können. In einem Dual Quaternion lassen sich also sowohl Rotation als auch Translation speichern.
Inhaltsverzeichnis
Definition
Ein Dual Quaternion dq ist wie folgt definiert:
dq = r + e*d
wobei r und d Quaternionen sind und e eine imaginäre(?) Zahl mit der Eigenschaft
e² = e*e = 0
r nennt man reellen Teil und d heißt dualer Teil von dq.
Arithmetik
Addition
Die Addition zweier Dual Quaternions geschieht komponentenweise:
dq1 = r1 + e*d1 dq2 = r2 + e*d2 dq1 + dq2 = r1+r2 + e*(d1+d2)
Die Subtraktion funktioniert analog.
Multiplikation
Die Multiplikation mit einem anderen Dual Quaternion ist etwas komplizierter. Seien dq, dq1 und dq2 definiert wie bei oben. Dann gilt:
dq = dq1 * dq2 <=> r = r1 * r2 d = (r1 * d2) + (d1 * r2)
Wobei beachtet werden sollte, dass hier jeweils drei Multiplikationen von Quaternionen (also nicht etwa das Skalarprodukt o.ä.) stattfinden. Wie schon bei Quaternionen und Matrizen gilt das Kommutativgesetz hier nicht! Das heißt dq1*dq2 ist nicht immer gleich dq2*dq1.
Operationen in der 3D-Grafik
Im Folgenden ist es wichtig festzulegen, in welcher Reihenfolge man die Komponenten der Quaternionen speichert. |
Zur Erinnerung: Ein Quaternion q hat folgende Form:
q = a+ b*i +c*j + d*k
Während im Artikel Quaternion eine andere Reihenfolge gewählt wurde, speichern wir Quaternionen nun als 4-Komponenten-Vektor (in GLSL-Schreibweise vec4), wobei
x = b y = c z = d w = a // letzte Komponente!!!
Dies entspricht der offenbar am weitesten verbreiteten Reihenfolge.
Setzen der Translation
Wir möchten, dass dq Vektoren um den Translationsvektor t verschiebt.
r.x = r.y = r.z = 0 // Identitäts-Quaternion r.w = 1 // für den reellen Teil d.x = t.x * 0.5 d.y = t.y * 0.5 d.z = t.z * 0.5 d.w = 0
Setzen der Rotation
Wir möchten, dass mit dq transformierte Vektoren um den Winkel phi um die Achse A gedreht wird.
r.x = A.x * sin(phi) r.y = A.y * sin(phi) r.z = A.z * sin(phi) r.w = cos(phi)
d.x = d.y = d.z = d.w = 0
Transformation eines Vektors
Wir möchten den Vektor v transformieren und erhalten den resultierenden Vektor v'
v' = v + 2 * (cross(r.xyz, cross(r.xyz, v) + r.w*v) + r.w*d.xyz - d.w*r.xyz + cross(r.xyz, d.xyz))
Interpolation
Der Hauptgrund, warum man in einigen Anwendungen Dual Quaternions gewöhnlichen Matrizen vorzieht, ist die gute Interpolierbarkeit. Wir möchten dq1 und dq2 linear interpolieren:
dq = dq1*(1-f) + dq2*f <=> r = r1*(1-f) + r2*f d = d1*(1-f) + d2*f
Dies entspricht der GLSL-Funktion mix().
Normalisieren
Nach der Interpolation besteht die Gefahr, dass das Dual Quaternion nicht mehr normalisiert ist. Das lässt sich beheben:
r = normalize(r1) // normalize() wie in GLSL d = d1 - r * dot(r, d1)
So wird dq die normalisierte Form von dq1. Die Reihenfolge der beiden Zeilen ist wichtig.
Vergleich zu anderen Darstellungen
4x4-Matrix
- Ein Dual Quaternion benötigt nur halb so viel Speicherplatz wie eine 4x4-Matrix (2 statt 4 uniform-Register)
- Eine Matrix lässt sich im Allgemeinen nicht sinnvoll interpolieren. Die lineare Interpolation von Dual Quaternions liefert dagegen genau das Ergebnis, was man i.A. erwartet und v.a. für Charakteranimation mit BoneWeights braucht.
- Die Transformation eines Vektors mit einer Matrix ist schneller (4 mal dot) als mit einem Dual Quaternion (siehe oben).
Quaternion + Translationsvektor
- Ein Dual Quaternion benötigt theoretisch einen float mehr, da ein Translationsvektor nur drei Komponenten hat. Bei der Anzahl der Shader-Register sind beide Lösungen gleichwertig.
- Interpolation: ToDo
- Transformation eines Vektors: ToDo
Links
Eine umfangreiche Implementation von DualQuaternions in C++ (In den Dateien Quaternion.cpp, Quaternion.hh, QuaternionInl.hh, QuaternionOperators.hh)