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...


Anmelden zum Antworten