使用四元数围绕最初以欧拉角表示的轴旋转矢量

时间:2013-06-07 12:34:30

标签: 3d rotation geometry quaternions virtual-reality

我目前正在处理X-Plane plugin to add support for the Oculus Rift,而且我在使用四元数进行轮换方面遇到了问题。我之前用旋转矩阵或Euler角度做过这种事情,但由于四元数似乎是现在的方式,我有机会学习它们。四元数也是Oculus SDK似乎本身使用的,因此使用它们是阻力最小的路径。

我试图解决的问题是将摄像机定位在飞行员头部的位置,因为飞机本身会改变其飞行方向。这对我来说似乎很简单。我有一个向量,表示飞行员头部与飞机重心的相对位置,我想围绕飞机 z 向量旋转 roll 度。

这是我现在的代码。我认为这是正确的,但运行此代码会产生一个太高的位置......在飞机顶部上方的某个位置,随着平面方向的变化,以一种圆形图案移动。此外,如果我尝试将头部矢量旋转0度(通过将 phi 设置为0),我得到相同(或至少类似的)奇怪的结果,所以我必须设置我的quat或错误的东西

    //get the vector to the players head relative to the plane's center of gravity
    float headX = XPLMGetDataf(XPLMFindDataRef("sim/aircraft/view/acf_peX"));
    float headY = XPLMGetDataf(XPLMFindDataRef("sim/aircraft/view/acf_peY"));
    float headZ = XPLMGetDataf(XPLMFindDataRef("sim/aircraft/view/acf_peZ"));

    //the planes orientation in euler angles
    float theta = XPLMGetDataf(XPLMFindDataRef("sim/flightmodel/position/theta")) * (M_PI / 180.0f);
    float psi = XPLMGetDataf(XPLMFindDataRef("sim/flightmodel/position/psi"))  * (M_PI / 180.0f);
    float phi = XPLMGetDataf(XPLMFindDataRef("sim/flightmodel/position/phi"))  * (M_PI / 180.0f);

    //convert euler angles into a vector for our axis or rotation
    float planeVecX = cos(psi)*cos(theta);
    float planeVecY = sin(psi)*cos(theta);
    float planeVecZ = sin(theta);

    //make some vectors
    Vector3<float> *headVector = new Vector3<float>(headX, headY, headZ);
    headVector->Normalize();
    Vector3<float> *planeVector = new Vector3<float>(planeVecX, planeVecY, planeVecZ);
    planeVector->Normalize();


    //Make a quaternion for our rotation
    Quat<float> *planeQuat = new Quat<float>(*planeVector, phi);

    planeQuat->Normalize();

    //rotate headVector by plane quat
    Vector3<float> rotatedHeadVec = planeQuat->Rotate(*headVector);

    //output our final camera position and orientation
    outCameraPosition->x = planeX + rotatedHeadVec.x;
    outCameraPosition->y = planeY + rotatedHeadVec.y;
    outCameraPosition->z = planeZ + rotatedHeadVec.z;
    outCameraPosition->pitch = theta * (180.0f / M_PI);
    outCameraPosition->heading = psi * (180.0f / M_PI);
    outCameraPosition->roll = phi * (180.0f / M_PI);

TIA的帮助。

1 个答案:

答案 0 :(得分:0)

原来,x平面与坐标系的方向不一致。这段代码有正确的想法,但是使用从X-Plane获得的数据是错误的。