Euler-Winkel nach Quaternion
-
Hi,
zur Zeit stelle ich Rotationen mittels Euler-Winkeln da, das würde ich gerne auf Quaternions umstellen.
Meine Funktion um Euler-Winkel zu einem Quaternion zu konvertieren, sieht so aus:
Quat Quat::fromPitchYawRoll_radian( float pitch, float yaw, float roll ) { float p = pitch / 2.0f; float y = yaw / 2.0f; float r = roll / 2.0f; float sinp = sin(p); float siny = sin(y); float sinr = sin(r); float cosp = cos(p); float cosy = cos(y); float cosr = cos(r); Quat q; q.setX( sinr * cosp * cosy - cosr * sinp * siny ); q.setY( cosr * sinp * cosy + sinr * cosp * siny ); q.setZ( cosr * cosp * siny - sinr * sinp * cosy ); q.setW( cosr * cosp * cosy + sinr * sinp * siny ); q.normalize(); return q; }
Der Code ist fast 1-zu-1 von hier übernommen: http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
Leider habe ich das Problem, dass meine Quaternions irgendwie immer um die falschen Achsen rotieren. Ich dachte erst, dass ich einfach nur yaw, pitch oder roll vertauscht hätte, aber das ist es nicht. Zum Vergleich habe ich mir mit den gleichen Winkeln mal ein Quaternion mit dem DirectX-SDK erzeugt.
int main(int argc, char** argv) { D3DXQUATERNION dxQuat; D3DXQuaternionRotationYawPitchRoll( &dxQuat, 20 * math::DEG2RAD, 10 * math::DEG2RAD, 30 * math::DEG2RAD ); Quat myQuat = Quat::fromPitchYawRoll_radian( 10 * math::DEG2RAD, 20 * math::DEG2RAD, 30 * math::DEG2RAD ); std::cout << "dxQuat.x " << dxQuat.x << std::endl; std::cout << "dxQuat.y " << dxQuat.y << std::endl; std::cout << "dxQuat.z " << dxQuat.z << std::endl; std::cout << "dxQuat.w " << dxQuat.w << std::endl; std::cout << std::endl; std::cout << "myQuat.x " << myQuat.x() << std::endl; std::cout << "myQuat.y " << myQuat.y() << std::endl; std::cout << "myQuat.z " << myQuat.z() << std::endl; std::cout << "myQuat.w " << myQuat.w() << std::endl; }
Ausgabe:
dxQuat.x 0.189308 dxQuat.y 0.0381346 dxQuat.z 0.239298 dxQuat.w 0.951549 myQuat.x 0.239298 myQuat.y 0.127679 myQuat.z 0.144878 myQuat.w 0.951549
(das DX-Quaternion funktioniert übrigens korrekt, alle Rotationen sind so wie sie sein sollen)
Was macht DirectX anders? bzw. was mache ich falsch? Ich hab irgendwie den Verdacht, dass das Koordinatensystem (Rechts- vs. Linkshändig) da mit reinspielt, konnte zu dem Thema aber nix finden...
Ich bin für jeden Tip dankbar
Gruß
eXi
-
Sind deine Eingabeparameter im Bogenmaß oder vielleicht in Grad? Bei letzterem solltest Du diese ins Bogenmaß umrechnen bevor Du den Sinus und Cosinus damit fütterst...