Matrix multiplication is not commutative. What is

2019-03-06 18:54发布

I basically have this problem:

Generic Simple 3D Matrix Rotation Issue

and it is driving me mad. I have been on Google for hours but cannot find any posts about solving the problem mathematically. How do I successfully rotate an object around 3 axis with a matrix and avoid this issue?

Thanks.

3条回答
smile是对你的礼貌
2楼-- · 2019-03-06 19:16

The solution/workaraound is to apply the rotations in the correct order.

If you have rotation matrices A, B and C and want to apply them to matrix M in order A, B, C then the solution is:

First apply A:

A * M

Then B:

B * A * M

And finally C:

C * B * A * M

If you want to apply ABC frequently you can precalculate the combined rotation matrix R:

R = C * B * A

and then you can apply R to M:

R * M
查看更多
Summer. ? 凉城
3楼-- · 2019-03-06 19:20

Thanks for all your help. I have found the answer here:

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

The solution is: "One easy way to work around this problem is to keep a second matrix around that will store all of the accumulated rotations." :-)

查看更多
Evening l夕情丶
4楼-- · 2019-03-06 19:21

If I get it right you want to rotate direct object transform matrix around its own axises.

  • in that case it is really simple (but I also spend much time solving this years back)
  • M0 is original object matrix
  • R is transformation you want to apply (rotation)
  • M1 is the result new object matrix
  • M1 = Inverse(Inverse(M0)*R)

That is all. you just have to add 4x4 inverse matrix routine to your code for example here is mine

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;
        }
  • hope I did not forget to copy something
  • usage is matrix_inv(dst,src)
  • returns inverse matrix of src to dst
  • both src and dst are double[16] linear arrays representing 4x4 transform matrix

[Edit1] 3x3 matrix

Mine matrix layout is this (OpenGL like):

double M[16];
a00 a04 a08 a12
a01 a05 a09 a13
a02 a06 a10 a14
a03 a07 a11 a15
  • where a?? is ??-th value from M[]

Now if you want to use 4x4 inverse of 3x3 matrix just do this

double m[9];
b00 b03 b06 0
b01 b04 b07 0
b02 b05 b08 0
0   0   0   1
  • where b?? is ??-th value from your 3x3 m[]
  • so load 4x4 matrix this way
  • invert
  • and extract 3x3 matrix back
  • You can always rewrite mine 4x4 inverse to 3x3 (I am too lazy to do that)
  • but it will get very simplified because determinant and sub-determinants will get very simple

just to be sure you get it right m[3*3] -> M[4*4] will be like this:

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;

And backwards m[3*3] <- M[4*4] will be like this:

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];
查看更多
登录 后发表回答