JS glMatrix: Rotation quaternion

Hallo,
ich bin etwas am Knobeln, aber für euch (Marco viell. :smiley: ) ist es bestimmt einfach.
Ich benutze das JavaScript framework glMatrix (und WebGL)…
Im Laufe einer Animation möchte ich die Model-Matrix drehen und translatieren.

var val1 = fromTo(0, 2, diffT);
mat4.fromRotationTranslation(mMatrix, [0, 0, 1, Math.radians(210)], [val1, 0.0, 0.0]);

http://glmatrix.net/docs/mat4.html

Wie man sieht, soll das Model erst um 210 Grad um die Z-Achse gedreht werden, und dann im Laufe der Animation von [0.0, 0.0, 0.0] bis [2.0, 0.0, 0.0] translatiert werden.
Das Drehen funktioniert allerdings nicht, und ich weiß nicht genau, was mit Rotation quaternion gemeint sein könnte…

Quaternionen sind “vierdimensionale Zahlen”, und Quaternionen mit Absolutbetrag 1 können verwendet werden, um Drehungen zu beschreiben. Im Gegensatz zu Systemen mit Euler-Winkeln kann man leicht eine direkte Drehung von einer Position zu einer bliebigen anderen Position berechnen.

Danke Landei. Es funktioniert inzwischen:

Allerdings habe ich die Funktionweise und Erstellung von diesen Quaternionen noch nicht verstanden.

Die braucht man nicht unbedingt “in aller Tiefe” zu verstehen.

Man kann Rotationen auf verschiedene Arten beschreiben.

  1. Euler-Winkel (x,y,z) : Wie weit man um die jeweilige Achse dreht
  2. Axis-Angle: Rotationsachse (x,y,z) und Winkel (w)
  3. Quaternionen (x,y,z,w)
  4. Eine 3x3 oder 4x4-Matrix

Option 1. reicht nicht (Gimbal Lock. Es gibt keinen Homöomorphismums vom R3 auf den SO(3)).
Option 4. ist Verschwendung (12-15 floats), und man kann die Rotation nicht vernünfig “Händisch” angeben. Außerdem kann eine Matrix ja VIEL mehr beschreiben als nur eine Rotation
Optionen 2. und 3. sind sehr ähnlich, allerdings haben Quaternionen noch einige schöne Mathematische Eigenschaften, die man ausnutzen kann (speziell für die Interpolation).

Danke für eine Beschreibung der Möglichkeiten der Rotation. Das ist echt spitze. Aber i-etwas mache ich bei der Erstellung des Quaternions falsch, mit [0, 0, 1, Math.radians(210)] wird das Dreieck einfach „vergrößert“. Ich möchte eine Drehung um 210 Grad um die Z-Achse erreichen. radians ist so definiert (daran kann es nicht liegen):

Math.radians = function (deg)
{
    return deg * (Math.PI / 180);
};

Beispiele für Quaternionen und glMatrix sind leider sehr rar.


Außerdem muss ich die Mathematik dieser Drehungen für eine Prüfung bis „in fast aller Tiefe“ leider „auswendig verstehen“. :frowning:
Also, ich werd noch mal ein Buch wälzen müssen.


###Edit
Ich hab noch einen ziemlich „groben“ Fehler gefunden, es sollte immer erst rotiert werden (wenn das „Objekt“ noch im „Umkreismittelpunkt“ ist), und dann sollte es translatiert werden.

Ein Quaternion “händisch” zu erstellen ist schwierg. Man kann da nicht einfach irgendwelche Zahlen reinhacken. Es gibt Umrechner. In den meisten Libraries gibt es zum Glück irgendwelche “Axis+Angle -> Quaternion”-Umrechnungsfunktionen. Ansonsten fand ich http://quaternions.online/ gelegentlich ganz hilfreich (auch wenn das Eulerwinkel verwendet - etwas ähnliches gibt es sicher auch für Axis+Angle)

Es gibt solche Umrechner:

quote fromRotationTranslation(out, q, v) → {mat4}
Creates a matrix from a quaternion rotation and vector translation This is equivalent to (but much faster than): mat4.identity(dest); mat4.translate(dest, vec); var quatMat = mat4.create(); quat4.toMat4(quat, quatMat); mat4.multiply(dest, quatMat);
Parameters:
Name Type Description
out mat4 mat4 receiving operation result
q quat4 Rotation quaternion
v vec3 Translation vector[/quote]

quote getRotation(out, mat) → {quat}
Returns a quaternion representing the rotational component of a transformation matrix. If a matrix is built with fromRotationTranslation, the returned quaternion will be the same as the quaternion originally supplied.
Parameters:
Name Type Description
out quat Quaternion to receive the rotation component
mat mat4 Matrix to be decomposed (input)[/quote]

Siehe auch hier: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/

Leider verstehe ich das nicht so ganz. Aber wenn es nicht einfach händisch möglich ist, dann nutze ich erstere Funktion nicht.


Nicht so super Qualität, aber ich hab das hinbekommen: