2013-11-01 31 views
1

我有以下JSFiddle http://jsfiddle.net/3vf9J/这突出了我的问题。CSS matrix3d计算不正确,但为什么?

我跟着就如何使一个函数来CSS结合导向转变成一个Matrix3D这样我就可以比苹果每次一个多。

不幸的是我无法正常工作。围绕一个轴简单旋转180度,最终看起来更像135度,所以我清楚地发现一些数学错误。

能理解矩阵的人能帮助我吗?

我的功能看起来是这样的:

var generateRotationMatrix = function(x, y, z, tx, ty, tz) { 
    var a = x; 
    var b = y; 
    var c = z; 

    var rotationXMatrix = $M([ 
     [1,0,0,0], 
     [0,Math.cos(a), Math.sin(-a), 0], 
     [0,Math.sin(a), Math.cos(a), 0], 
     [0,0,0,1] 
    ]); 

    var rotationYMatrix = $M([ 
     [Math.cos(b), 0, Math.sin(b),0], 
     [0,1,0,0], 
     [Math.sin(-b), 0, Math.cos(b), 0], 
     [0,0,0,1] 
    ]); 

    var rotationZMatrix = $M([ 
     [Math.cos(c), Math.sin(-c), 0, 0], 
     [Math.sin(c), Math.cos(c), 0, 0], 
     [0,0,1,0], 
     [0,0,0,1] 
    ]); 

    var translationMatrix = $M([ 
       [1,0,0,0], 
       [0,1,0,0], 
       [0,0,1,0], 
       [tx,ty,tz,1] 
        ]); 
    var tM = rotationXMatrix 
      .x(rotationYMatrix) 
      .x(rotationZMatrix) 
     .x(translationMatrix); 

    var s = "matrix3d(" 
    s += tM.e(1,1).toFixed(10) + "," + tM.e(1,2).toFixed(10) + "," + tM.e(1,3).toFixed(10) + "," + tM.e(1,4).toFixed(10) + "," 
    s += tM.e(2,1).toFixed(10) + "," + tM.e(2,2).toFixed(10) + "," + tM.e(2,3).toFixed(10) + "," + tM.e(2,4).toFixed(10) + "," 
    s += tM.e(3,1).toFixed(10) + "," + tM.e(3,2).toFixed(10) + "," + tM.e(3,3).toFixed(10) + "," + tM.e(3,4).toFixed(10) + "," 
    s += tM.e(4,1).toFixed(10) + "," + tM.e(4,2).toFixed(10) + "," + tM.e(4,3).toFixed(10) + "," + tM.e(4,4).toFixed(10) 
    s += ")"; 
    return s; 
} 

请注意我用Sylvester做我的矩阵数学(倍增)

回答

1

更新(2014年4月22日)通过thisiate - 原作者

由于我正在做类似的事情,所以这个问题出现在我的脑海里,所以在仔细观察它的时候,我注意到了这个错误,并发现了它的原因。这里是一个简短的解释。

平移矩阵是错误的:

var translationMatrix = $M([ 
      [1,0,0,0], 
      [0,1,0,0], 
      [0,0,1,0], 
      [tx,ty,tz,1] 
       ]); 

需求被改写:

var translationMatrix = $M([ 
      [1,0,0,tx], 
      [0,1,0,ty], 
      [0,0,1,tz], 
      [0,0,0,1] 
       ]); 

这个小错误解释了为什么你看到一个奇怪的结果。矩阵乘法中某些东西将乘以零的3个位置现在乘以变换变量,从而计算出不同的角度。而且,任何变换都不会被应用,因为0基本上是常量。此外,tz的位置最初影响处理透视的矩阵部分。

我相信这应该解决矩阵部分的任何问题。我原来的回答是基于rotate3d被限制在360度(0-359)的事实。由于正弦波和余弦波的周期,插值为模数360值时,不能通过360或-360。例如rotateX valueX1 rotateY valueY1rotateX valueX2 rotateY valueY2之间的变换实际上会直接内插并在CSS引擎内部使用该结果(所有这些变换将由视频处理器(如果可用的话而不是CPU)进行硬件加速)并且将比计算矩阵变换更快。

原来的答复如下:

马特,如果你想单独申请多个转换,并有一个简单的方法来改变的变换(说rotateX),see this answer I gave for a different solution每个单独的元素。

你不需要使用matrix3d来得到你想要的。浏览器将处理结果转换(如果可用,使用图形处理器)。意识到旋转变换的顺序写入影响最终输出随着参考系的变化而变化很重要。例如,当您执行rotateY(180deg)时,现在引用框架会将X轴和Z轴更改为它们的对立面,因为您现在正盯着元素的背面(负X值位于右侧) Y轴向左为正,同样,Z轴负值现在比0更接近你,正Z轴值进入屏幕)。

为了便于弄清楚多次旋转的元素会发生什么,取一张卡片或类似的纸张,绘制X轴和Y轴,然后将牙签穿过原点,使其更多地穿过请注意,在浏览器中,Y向下,而不是向上。现在从第一次旋转开始,用纸做3d。重复所有的旋转,然后做任何翻译,然后缩放(你将不得不想象这个),等等。