简体   繁体   English

CSS matrix3d计算不正确,但是为什么呢?

[英]CSS matrix3d calculation is not right, but why?

I have the following JSFiddle http://jsfiddle.net/3vf9J/ which highlights my issue. 我有以下JSFiddle http://jsfiddle.net/3vf9J/突出了我的问题。

I've followed a guide on how to make a function to combine css transforms into a matrix3d so I can apple more than one at a time. 我遵循了有关如何制作将CSS转换组合成matrix3d的函数的指南,这样我一次就能获得多个。

Unfortunately I've failing to make it work properly. 不幸的是,我无法使其正常运行。 A simple rotation of 180 degrees about one axis, ends up looking more like 135 degrees, so I've clearly got some maths wrong somewhere. 围绕一个轴简单地旋转180度,最终看起来更像135度,因此我显然在某些地方出现了一些数学错误。

Can anyone who understands matrices help me out? 懂矩阵的人可以帮助我吗?

My function looks like this: 我的函数如下所示:

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;
}

Please note I'm using Sylvester to do my matrix maths (the multiplication) 请注意,我正在使用Sylvester进行矩阵数学运算(乘法)

Update (April 22, 2014) by thisiate - original author 此作者的原始更新(2014年4月22日)

This problem was in the back of my mind as I am doing something similar, so while looking at it more closely, I noticed the bug and found out why it occurred. 当我做类似的事情时,这个问题就浮现在我的脑海中,因此,当我仔细观察它时,我注意到了该错误并找出了为什么会发生。 Here is a brief explanation. 这是一个简短的解释。

The translation matrix is wrong: 翻译矩阵是错误的:

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

Needs to be rewritten as: 需要重写为:

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

This small mistake explains why you are seeing a strange result. 这个小错误解释了为什么您看到奇怪的结果。 The 3 places where something would multiply to zero in the matrix multiplications are now multiplied by the transform variables thus computing a different angle. 现在,将在矩阵乘法中将某物乘以零的3个位置乘以变换变量,从而计算出不同的角度。 Also, any transform would not be applied as 0's are given as basically constants. 同样,任何变换都不会应用,因为0基本上是常量。 Further, the position of tz originally affects the part of the matrix dealing with perspective. 此外, tz的位置最初会影响矩阵处理透视的部分。

I believe that this should fix any problems with matrix part. 我相信这应该解决矩阵部分的任何问题。 My original answer is based on the fact that rotate3d is limited to 360 degrees (0-359). 我的原始答案基于以下事实:rotate3d限制为360度(0-359)。 One cannot pass through 360 nor -360 as a transform between is interpolated as a modulus 360 value due to the period of the sine and cosine waves. 由于正弦波和余弦波的周期,不能将360和-360转换为模数360值,因此无法通过。 Transforms between say rotateX valueX1 rotateY valueY1 to rotateX valueX2 rotateY valueY2 will actually interpolate each directly and use that result inside the CSS engine (all these transforms will be hardware accelerated by the video processor if available instead of the CPU) and will be faster than computing the matrix transform. 实际上,在rotateX valueX1 rotateY valueY1rotateX valueX2 rotateY valueY2之间的转换实际上将直接对每个插值进行插值并在CSS引擎内部使用该结果(如果可用,而不是CPU,所有这些转换将由视频处理器进行硬件加速),并且比计算更快矩阵变换。

Original Answer below: 原始答案如下:

Matt, if you want solely to apply multiple transforms and have an easy way to change each individual element of the transform (say rotateX), see this answer I gave for a different solution . 马特(Matt),如果您只想应用多个变换,并且有一种简单的方法来更改变换的每个元素(例如rotateX), 请参阅我为其他解决方案提供的答案

You do not need to use the matrix3d to get what you want. 您无需使用matrix3d即可获得所需的内容。 The browser will work out the resulting transform (using the graphics processor if available). 浏览器将计算出最终的转换结果(如果可用,使用图形处理器)。 It is important to realize that the order that the rotation transforms are written in affect the final output as the frame of reference changes. 重要的是要意识到,随着参考框架的变化,旋转变换的写入顺序会影响最终输出。

For example, when you do a rotateY(180deg), the frame of reference now changes the X and Z axis to their opposites as you are now staring at the back of the element (negative X values are to the right of the Y-axis, positive to the left, likewise, the Z-axis negative values now are closer to you than 0 and the positive Z-axis values are into the screen). 例如,当您进行一次旋转Y(180deg)时,参照系现在将X和Z轴更改为相反的方向,因为您现在正盯着元素的背面(负X值位于Y轴的右侧) ,即左侧的正值,现在Z轴的负值现在比0更接近您,并且Z轴的正值进入屏幕了。

To make it easy to work out what happens to an element with multiple rotations, take a piece of cardstock or similar paper, draw the X and Y axes, and put a toothpick through the origin with more of it sticking through the top side (positive z-axis) of the paper, note that in the browser Y is down, not up. 为了便于计算旋转多次的元素所发生的情况,拿出一张卡片纸或类似的纸,画出X轴和Y轴,然后将一根牙签穿过原点,而更多的则粘在顶侧(正注意,在浏览器中Y是向下而不是向上。 Now start with the first rotation and do it in 3d with the paper. 现在从第一个旋转开始,并在3d纸上进行旋转。 Repeat for all rotations, then do any translations, then scales (you'll have to imagine this one), etc. 重复所有旋转,然后进行任何平移,然后缩放(您必须想象一下),等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM