Matrix.rotateM android API导致错误旋转Matrix

时间:2014-08-04 00:31:48

标签: math matrix graphics opengl-es rotation

我在做自己的collada解析器。动画关节时,我有一个要应用的有序转换列表。当应用所有这些时,我得到一个矩阵,即联合节点矩阵。我认为这是如何运作的。

据我所知,该系统的工作方式是,在第一次转换中,将其应用于单位矩阵,然后将结果矩阵连续应用到下一个转换,直到最后一个转换。

将转换变换应用于矩阵看起来没问题,但是当它旋转时会发生一些奇怪的事情:

例如:两个第一个转换是围绕z轴的平移和旋转。这看起来像这样:

<translate> -0.6289 63.7555 0.008499979 </translate>
<rotate>0 0 1 -5.00881</rotate>

使用Matrix.translateM和Matrix.rotateM android api函数我得到了这个矩阵:

storedMatrix  =

  0.9961813    0.0873089    0.  - 0.6289     
- 0.0873089    0.9961813    0.    63.7555    
  0.           0.           1.    0.0085000  
  0.           0.           0.    1.   

使用SciLAB(它是一个替代Matlab的免费软件)我编写了一个脚本来计算平移和旋转矩阵。这是我在脚本中添加的代码:

function [storedMatrix] = rotateStoredMat(x_axis,y_axis,z_axis,angle_amount)

    // t is angle amount, x is x_axis, and...

    // ESTA ES LA FÓRMULA (NO SACADA DE WIKIPEDIA PERO ALLI ESTA IGUAL) PARA MATRICES ORGANIZADAS POR COLUMNAS
    // FROM WIKIPEDIA: 
    // x*x * (cos(t) - 1) + cos(t)    x*y * (cos(t) - 1) + (z*sin(t))  x*z * (cos(t) - 1) - (y*sin(t))
    // x*y * (cos(t) - 1) - z*sin(t)  y*y * (cos(t) - 1) + cos(t)      y*z * (cos(t) - 1) + (x*sin(t))
    // x*z * (cos(t) - 1) + y*sin(t)  y*z * (cos(t) - 1) - (x*sin(t))  z*z * (cos(t) - 1) + cos(t)

    global storedMatrix;
    xx = x_axis * x_axis;
    xy = x_axis * y_axis;
    xz = x_axis * z_axis;

    yy = y_axis * y_axis;
    yz = y_axis * z_axis;

    zz = z_axis * z_axis;
    cost = cos(angle_amount);
    sint = sin(angle_amount);
    mat = [
        xx*(cost -1)+cost           xy*(cost -1)+(z_axis*sint)          xz*(cost -1)-(y_axis*sint)      0;
        xy*(cost -1)-z_axis*sint    yy*(cost -1)+cost                   yz*(cost -1)+(x_axis*sint)      0;
        xz*(cost -1)+y_axis*sint    yz*(cost -1)-(x_axis*sint)               zz*(cost -1)+cost               0;
        0                           0                                   0                               1;

    ];

    storedMatrix = mat * storedMatrix;

endfunction

function [storedMatrix] = translateStoredMat(x,y,z)

    global storedMatrix;

    mat = [
        1           0          0        x;
        0           1          0        y;
        0           0          1        z;
        0           0          0        1;

    ];

    storedMatrix = mat * storedMatrix;

endfunction

function [storedMatrix] = loadIdentity()
    global storedMatrix;

    mat = [
        1           0          0        0;
        0           1          0        0;
        0           0          1        0;
        0           0          0        1;

    ];
    storedMatrix = mat;

endfunction

使用这个“帮助”脚本,这是我得到的矩阵:

   ans  =

    0.2920992    0.9563880    0.           60.791296  
  - 0.9563880    0.2920992    0.           19.224402  
    0.           0.         - 0.4158016  - 0.0035343  
    0.           0.           0.           1. 

那么,我的scilab脚本错了吗?我是否以错误的方式应用了rotateM功能? 我可以说的是骨头和关节被绘制在错误的位置,所以我说我没有计算它们并且我的scilab给了我正确的矩阵来使用。

你能帮帮我吗?您是否需要更多信息来评估此问题并给出答案?请随意询问。

1 个答案:

答案 0 :(得分:0)

差异有几个原因:

  1. rotateM()以度为单位,而您编写的脚本将其视为以弧度为单位的角度。
  2. 您的旋转矩阵计算与我在维基百科上看到的公式(http://en.wikipedia.org/wiki/Rotation_matrix)不匹配。所有条款看起来都有所不同。例如,您在维基百科页面的(cost - 1)
  3. 处使用(1 - cost)
  4. rotateM()产生的相比,您的旋转矩阵看起来是转置的。
  5. 当您使用Matrix函数时,与您对脚本的操作相比,您将以相反的顺序将两个矩阵相乘。