getRotX in Transform3D

Hallo,

im Zuge eines größeren Projektes muss ich aus einer Rotationsmatrix (Klasse Transform3D) die Rotation in eine X-,Y- und Z-Komponente zerlegen, um anhand derer ein BVH-Animaionsfile zu schreiben.
Transform3D hat zwar Funktionen um diese zu setzen (rotX, rotY und rotZ), aber keine um diese Werte auszulesen.

Wie mache ich das am besten?

Gruß und ein schönes WE,

Frederic

Hi,

das machst Du am einfachsten mit dem Algorithmus zur QR-Zerlegung, der mit Givensrotationen arbeitet. Die Givensrotationen sind hier gerade die Rotationen um die Koordinatenachsen.

http://www.matheplanet.com/matheplanet/nuke/html/vie…
http://www.matheplanet.com/matheplanet/nuke/html/vie…
http://www.matheplanet.com/matheplanet/nuke/html/vie…

Gruß Lutz

Hallo und danke für die kompetente Antwort :smile:

ui, hätte ich doch blos mal in Mathe aufgepasst ^^
Ich hab sowas schon mal gesehen, aber das ist schon etwas her.

Ich habe in einer lib eine Funktion gefunden, die wahrscheinlich diese Berechnung durchführen sollte. Im Test waren die ausgegebenen Zahlen allerdings nicht korrekt.
Leider verstehe ich nicht, was diese Funktion genau rechnet, und ob das überhaupt das ist was ich brauche :frowning:

Hier der Code:

/**
* Returns MyMath angles from rotation part of the transform.
* (converted from Horde3D, utMath.h library)
*
* @return MyMath angles in vector, or null if MyMath not computable.
*/

public static Vector3d getEuler(Transform3D tf) {
Vector3d euler = new Vector3d();
tf.getScale(m_scale);
if (m_scale.x == 0 || m_scale.y == 0 || m_scale.z == 0)
return null;

// Detect negative scale with determinant and flip one arbitrary axis
if (! tf.getDeterminantSign())
m_scale.x = - m_scale.x;

tf.get(m_mat);
euler.x = Math.asin(-m_mat.m12 / m_scale.z);

// Special case: Cos[x] == 0 (when Sin[x] is +/-1)
double f = Math.abs(m_mat.m12 / m_scale.z);
if (f > .999f && f m00 = Cos[z] and m01 = Sin[z]
euler.z = Math.atan2(-m_mat.m01/m_scale.y, m_mat.m00/m_scale.x);
} else {
// Standard case
euler.y = Math.atan2(m_mat.m02/m_scale.z, m_mat.m22/m_scale.z);
euler.z = Math.atan2(m_mat.m10/m_scale.x, m_mat.m11/m_scale.y);
}
return euler;
}

Hi,

ich verstehe auch nicht, was diese Funktion genau ausrechnet. Evtl. funktioniert sie nur, wenn die Eingabe eine der Achsendrehungen ist. Wie da aber die Skalen mit reinspielen…

Gruß Lutz

http://www.gregslabaugh.name/publications/euler.pdf

hat eine ausführlich erklärte Anleitung, die einfacher ist, als mein Code. Der Pseudo-Code darin sollte sich einfach in eine lauffähige Prozedur umsetzen lassen.

Evtl. sollten die Tests auf Null in Tests auf kleine Werte geändert werden.

Gruß Lutz

Dieses PDF hilft definitiv weiter!

Ich versuche es noch am WE zu implementieren.

Vielen Dank :smile:

Aus Sicht

des unten genannten Artikels sollte auch dieser Code funktionieren, er liefert aber immer nur die erste der zwei Lösungen, was manchmal die unerwünschte sein kann.

Ich bin da etwas durch die Variablenbezeichnungen verwirrt worden.

Gruß Lutz