如何在Matrix3d上获得比例尺(x,y,z)和旋转量(x,y,z)?

时间:2019-03-28 11:04:16

标签: javascript matrix matrix-multiplication

在矩阵计算上,我在scale(x,y,z)rotation(x,y,z)方面有些挣扎。我目前正在用JS构建3D建模器程序,我一直在使用CSS标志进行转换,但是我决定继续使用矩阵。

var a1=1,a2=0,a3=0,a4=0,
    a5=0,a6=1,a7=0,a8=0,
    a9=0,a10=0,a11=1,a12=0,
    a13=0,a14=0,a15=0,a16=1,
        Rx=45,Ry=45,matrix=true;

var objMatrix = [];
var MDN = MDN || {};
        MDN.matrixArrayToCssMatrix = function (array) {
          return "matrix3d(" + array.join(',') + ")";
        }   

       var angX=Rx,angY=Ry,
                    MCpx=Math.cos(angX * Math.PI / 180),
                    MSpx=Math.sin(angX * Math.PI / 180),
                    MSnx=Math.sin(-angX * Math.PI / 180),
                    MCpy=Math.cos(angY * Math.PI / 180),
                    MSpy=Math.sin(angY * Math.PI / 180),
                    MSny=Math.sin(-angY * Math.PI / 180);
                if (matrix==true) {
                    a1= MCpy,
                    a2 = MSpx*MSpy,
                    a3= MCpx*MSpy,
                    a6 = MCpx,
                    a7 = MSnx,
                    a9 = MSny,
                    a10 = MSpx*MCpy,
                    a11 = MCpx*MCpy;
                     }

                    objMatrix = [
                    a1,   a2,    a3,   a4,
                    a5,   a6,    a7,   a8,
                    a9,   a10,   a11,  a12,
                    a13,  a14,   a15,  a16
                ];
                return objMatrix;
                }

function transform(){ 
            matrix(objMatrix); 
        var matrixToCSS = MDN.matrixArrayToCssMatrix( matrix(objMatrix) ); 
            document.getElementById("foo").style.transform = matrixToCSS; 
 }

到目前为止,有了上面的代码,我得到了translate(X,Y,Z)rotate(X,Y),其余的我只是无法弄清楚。

1 个答案:

答案 0 :(得分:0)

我在这里找到了解决方案, 只需按顺序创建3个矩阵,然后乘以(级联)即可得到结果。

参考PDF:a link

var objMatrix = [];
var MDN = MDN || {};
        function matrix(objMatrix) {
        MDN.matrixArrayToCssMatrix = function (array) {
          return "matrix3d(" + array.join(',') + ")";
        }  
    var PIh=Math.PI / 180;
    var angX=Rx,angY=Ry,angZ=rt,
        cosz=Math.cos(angZ * PIh),sinzp=Math.sin(angZ * PIh),sinzn=Math.sin(-angZ * PIh),
        cosx=Math.cos(angX * PIh),sinxp=Math.sin(angX * PIh),sinxn=Math.sin(-angX * PIh),
        cosy=Math.cos(angY * PIh),sinyp=Math.sin(angY * PIh),sinyn=Math.sin(-angY * PIh),
        a1=cosy,a2=sinxp*sinyp,a3=cosx*sinyp,a4=0,
        a5=0,a6=cosx,a7=sinxn,a8=0,
        a9=sinyn,a10=sinxp*cosy,a11=cosx*cosy,a12=0,
        a13=X,a14=Y,a15=Z,a16=1;    
   m1 = [
        [SX, 0,   0,  0],
        [0,  SY,  0,  0],
        [0,  0,   SZ, 0],
        [X,  Y,   Z,  1]];
   m2 = [
        [a1,  a2,  a3, a4],
        [a5,  a6,  a7, a8],
        [a9, a10, a11, a12],
        [0,  0,   0,   a16]];
   m3 = [
        [cosz,  sinzn, 0,   0],
        [sinzp, cosz,  0,   0],
        [0,     0,     1,   0],
        [0,     0,     0,   a16]];
    var m1row = m1.length, 
        m1col = m1[0].length, 
        m2col = m2[0].length,
        m3col = m3[0].length,
        proto = new Array(m1row);
      for (var r = 0; r < m1row; ++r) {
        proto[r] = new Array(m2col); 
        for (var c = 0; c < m2col; ++c) {
          proto[r][c] = 0;
          for (var i = 0; i < m1col; ++i) {
            proto[r][c] += m1[r][i] * m2[i][c];
          }
        }
      }
     var protorow = proto.length, 
         protocol = proto[0].length, 
          objMatrix = new Array(protorow);
      for (var r = 0; r < protorow; ++r) {
        objMatrix[r] = new Array(m3col); 
        for (var c = 0; c < m3col; ++c) {
          objMatrix[r][c] = 0;
          for (var i = 0; i < protocol; ++i) {
            objMatrix[r][c] += proto[r][i] * m3[i][c];
          }
        }
      }


      return objMatrix;
    }
document.getElementById("foo").style.transform = MDN.matrixArrayToCssMatrix( objMatrix );

注意:顺序很重要,M1 X M2 X M3 X P。