• OpenGL角轴


    概述


    OpenGL旋转矩阵

    旋转角度直接影响OpenGL GL_MODELVIEW矩阵的前三列,准确地说是向左、向上与向前三轴元素。例如,如果一沿X轴的单位向量(1,0,0)与任一3×3旋转矩阵相乘,旋转后的向量结果为:

    也就是说,旋转矩阵的第一列(m0,m1,m2)表示旋转后的做轴。同样,第二列为上轴,第三列为前轴。

    本文描述用旋转角度构造GL_MODELVIEW矩阵。

    旋转轴

    首先,我们看一看绕每个轴旋转:+X、+Y与+Z。我们以三种不同方式将三个轴投影到到一个平面,将要旋转的轴朝向你。正旋转方向为逆时针(右手规则)。

    绕左(X)轴旋转(Pitch)


    绕左轴(X)旋转

    上轴(Y)与前轴(Z)的初始值为(0,1,0)与(0,0,1)。如果左轴(X)旋转A°,因此新的上轴从(1,0,0)变换为X‘为(0,cosA,sinA),新的前轴(Z')变为(0,-sinA,cosA)。新轴作为3×3旋转矩阵的列分量插入近来。旋转矩阵变为:

    绕上(Y)轴旋转(Yaw,Heading)


    绕上轴(Y)旋转

    现在,我们旋转朝向你的向上向量B°。左(X)轴从(1,0,0)变为X’(cosB,0,-SinB)。前轴(Z)从(0,0,1)变换为Z‘(sinB,0,cosB)。

    绕前轴(Z)旋转(Roll)


    绕前轴(Z)旋转

    如果我们旋转前轴(Z)C°,初始左轴(1,0,0)变为X’(cosC,sinC,0),上轴(0,1,0)变为Y‘(-sinC,cosC,0)。

    角轴

    我们可以通过上面3个矩阵相乘的方式将这些分开的轴旋转结合成一个矩阵。注意矩阵乘法是不可呼唤的,因此,矩阵乘法的不同顺序产生不同的结果。共有6中不同的结合方式:RxRyRz、RxRzRy、 RyRxRz、RyRzRx、RzRxRy与RzRyRx

    组合旋转矩阵的左列为旋转后的左轴,中间列为上轴,右列为前轴。








    下面是RxRyRz结合的C++实例代码。它以Rz(roll)、Ry(yaw)、Rx(pitch)顺序执行3个旋转操作。左轴、上轴与前轴的结果可以用于构造GL_MODELVIEW矩阵。

    struct Vector3
    {
        float x;
        float y;
        float z;
        Vector3() : x(0), y(0), z(0) {}; // 创建时初始化
    };
     
    ///////////////////////////////////////////////////////////////////////////////
    //将欧拉(x,y,z)转换到(左, 上, 前)
    // 旋转矩阵的列代表左轴、上轴与前轴。
    // 旋转顺序为:Roll->Yaw->Pitch (Rx*Ry*Rz)
    // Rx: 绕X轴旋转, pitch
    // Ry: 绕Y轴旋转, yaw(heading)
    // Rz: 绕Z轴旋转, roll
    //    Rx           Ry          Rz
    // |1  0   0| | Cy  0 Sy| |Cz -Sz 0|   | CyCz        -CySz         Sy  |
    // |0 Cx -Sx|*|  0  1  0|*|Sz  Cz 0| = | SxSyCz+CxSz -SxSySz+CxCz -SxCy|
    // |0 Sx  Cx| |-Sy  0 Cy| | 0   0 1|   |-CxSyCz+SxSz  CxSySz+SxCz  CxCy|
    ///////////////////////////////////////////////////////////////////////////////
    void anglesToAxes(const Vector3 angles, Vector3& left, Vector3& up, Vector3& forward)
    {
        const float DEG2RAD = 3.141593f / 180;
        float sx, sy, sz, cx, cy, cz, theta;
    
        // 绕X轴旋转 (pitch)
        theta = angles.x * DEG2RAD;
        sx = sinf(theta);
        cx = cosf(theta);
    
        // 绕Y轴旋转 (yaw)
        theta = angles.y * DEG2RAD;
        sy = sinf(theta);
        cy = cosf(theta);
    
        // 绕Z轴旋转 (roll)
        theta = angles.z * DEG2RAD;
        sz = sinf(theta);
        cz = cosf(theta);
    
        // 确定左轴
        left.x = cy*cz;
        left.y = sx*sy*cz + cx*sz;
        left.z = -cx*sy*cz + sx*sz;
    
        // 确定上轴
        up.x = -cy*sz;
        up.y = -sx*sy*sz + cx*cz;
        up.z = cx*sy*sz + sx*cz;
    
        // 确定前轴
        forward.x = sy;
        forward.y = -sx*cy;
        forward.z = cx*cy;
    }
    

    英文原文:http://www.songho.ca/opengl/gl_anglestoaxes.html

    学习与分享
  • 相关阅读:
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    每日日报
    7.21Java入门--->第二节
    7.20Java入门--->第一节
  • 原文地址:https://www.cnblogs.com/hefee/p/3817450.html
Copyright © 2020-2023  润新知