矩阵乘法不是可交换的。什么是解决方案或解决方案?

时间:2014-08-06 10:20:48

标签: math matrix 3d rotation

我基本上有这个问题:

Generic Simple 3D Matrix Rotation Issue

这让我发疯了。我已经在谷歌上工作了几个小时,但找不到任何关于以数学方式解决问题的帖子。如何使用矩阵成功地围绕3轴旋转对象并避免此问题?

感谢。

3 个答案:

答案 0 :(得分:1)

解决方案/工作区将以正确的顺序应用旋转。

如果您有旋转矩阵A,B和C,并希望按照A,B,C的顺序将它们应用于矩阵M,那么解决方案是:

首先申请A:

A * M

然后B:

B * A * M

最后C:

C * B * A * M

如果您想经常应用ABC,可以预先计算组合旋转矩阵R:

R = C * B * A

然后你可以将R应用于M:

R * M

答案 1 :(得分:0)

如果我做对了你想要围绕它自己的轴旋转直接物体变换矩阵。

  • 在这种情况下,它非常简单(但我也花了很多时间来解决这些问题)
  • M0是原始对象矩阵
  • R是您想要应用的转化(轮换)
  • M1是结果新对象矩阵
  • M1 = Inverse(Inverse(M0)*R)

就是这样。你只需要为你的代码添加4x4逆矩阵例程,例如这里是我的

void  matrix_subdet    (double *c,double *a)
        {
        double   q[16];
        int     i,j;
        for (i=0;i<4;i++)
         for (j=0;j<4;j++)
          q[j+(i<<2)]=matrix_subdet(a,i,j);
        for (i=0;i<16;i++) c[i]=q[i];
        }
double matrix_subdet    (         double *a,int r,int s)
        {
        double   c,q[9];
        int     i,j,k;
        k=0;                            // q = sub matrix
        for (j=0;j<4;j++)
         if (j!=s)
          for (i=0;i<4;i++)
           if (i!=r)
                {
                q[k]=a[i+(j<<2)];
                k++;
                }
        c=0;
        c+=q[0]*q[4]*q[8];
        c+=q[1]*q[5]*q[6];
        c+=q[2]*q[3]*q[7];
        c-=q[0]*q[5]*q[7];
        c-=q[1]*q[3]*q[8];
        c-=q[2]*q[4]*q[6];
        if (int((r+s)&1)) c=-c;       // add signum
        return c;
        }
double matrix_det       (         double *a)
        {
        double c=0;
        c+=a[ 0]*matrix_subdet(a,0,0);
        c+=a[ 4]*matrix_subdet(a,0,1);
        c+=a[ 8]*matrix_subdet(a,0,2);
        c+=a[12]*matrix_subdet(a,0,3);
        return c;
        }
double matrix_det       (         double *a,double *b)
        {
        double c=0;
        c+=a[ 0]*b[ 0];
        c+=a[ 4]*b[ 1];
        c+=a[ 8]*b[ 2];
        c+=a[12]*b[ 3];
        return c;
        }
void  matrix_inv       (double *c,double *a)
        {
        double   d[16],D;
        matrix_subdet(d,a);
        D=matrix_det(a,d);
        if (D) D=1.0/D;
        for (int i=0;i<16;i++) c[i]=d[i]*D;
        }
  • 希望我没有忘记复制一些东西
  • 用法为matrix_inv(dst,src)
  • src的逆矩阵返回到dst
  • srcdst都是代表4x4转换矩阵的double[16]线性数组

[Edit1] 3x3矩阵

我的矩阵布局是这样的(类似OpenGL):

double M[16];
a00 a04 a08 a12
a01 a05 a09 a13
a02 a06 a10 a14
a03 a07 a11 a15
  • 其中a??是来自M[]
  • 的值

现在,如果您想使用3x3矩阵的4x4反转,请执行此操作

double m[9];
b00 b03 b06 0
b01 b04 b07 0
b02 b05 b08 0
0   0   0   1
  • 其中b??是 - 来自3x3 m[]
  • 的值
  • 所以以这种方式加载4x4矩阵
  • 转化
  • 并提取3x3矩阵
  • 你总是可以将我的4x4逆转换为3x3(我太懒了)
  • 但它会变得非常简化,因为决定因素和次决定因素会非常简单

只是为了确保你做对了m [3 * 3] - &gt; M [4 * 4]将是这样的:

M[ 0]=m[0];
M[ 1]=m[1];
M[ 2]=m[2];
M[ 3]=0.0;
M[ 4]=m[3];
M[ 5]=m[4];
M[ 6]=m[5];
M[ 7]=0.0;
M[ 8]=m[6];
M[ 9]=m[7];
M[10]=m[8];
M[11]=0.0;
M[12]=0.0;
M[13]=0.0;
M[14]=0.0;
M[15]=1.0;

向后m [3 * 3]&lt; - M [4 * 4]将是这样的:

m[0]=M[ 0];
m[1]=M[ 1];
m[2]=M[ 2];
m[3]=M[ 4];
m[4]=M[ 5];
m[5]=M[ 6];
m[6]=M[ 8];
m[7]=M[ 9];
m[8]=M[10];

答案 2 :(得分:0)

感谢您的帮助。我在这里找到了答案:

http://www.learnopengles.com/tag/rotation/

解决方案是:&#34;解决这个问题的一个简单方法是在第二个矩阵周围保存所有累积的旋转。&#34; : - )