CSS matrix3d计算不对,但为什么呢?

时间:2013-11-01 13:33:25

标签: javascript css css-transforms sylvester

我有以下JSFiddle http://jsfiddle.net/3vf9J/,它突出了我的问题。

我已经按照指南介绍了如何将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 个答案:

答案 0 :(得分:1)

更新(2014年4月22日)by 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)并且会更快比计算矩阵变换。

以下原始答案:

Matt,如果你只想应用多个变换并且有一个简单的方法来改变变换的每个单独元素(比如rotateX),see this answer I gave for a different solution

您无需使用matrix3d即可获得所需内容。浏览器将计算出最终的转换(使用图形处理器,如果可用)。重要的是要认识到旋转变换的顺序会随着参照系的变化而影响最终输出。

例如,当您执行rotateY(180deg)时,引用框现在将X和Z轴更改为它们的对立面,因为您现在正在盯着元素的背面(负X值位于元素的右侧) Y轴,向左为正,同样,Z轴负值现在比0更靠近你,正Z轴值进入屏幕)。

为了便于弄清楚多次旋转的元素会发生什么,拿一张卡片纸或类似纸张,画出X和Y轴,然后将牙签穿过原点,更多的牙签穿过顶部在纸张的侧面(正z轴),注意在浏览器中Y是向下,而不是向上。现在从第一次旋转开始,然后在纸上用3d做。重复所有旋转,然后进行任何翻译,然后进行缩放(你必须想象这个),等等。