我有以下 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做我的矩阵数学(乘法)
最佳答案
更新(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 个地方现在乘以变换变量,从而计算出不同的 Angular 。此外,任何转换都不会应用,因为 0 被作为基本常量给出。此外,tz
的位置最初会影响处理透视的矩阵部分。
我相信这应该可以解决矩阵部分的任何问题。我最初的回答是基于 rotate3d 被限制在 360 度(0-359)这一事实。由于正弦波和余弦波的周期,360 度和 -360 度之间的变换被内插为模数 360 度值。从 rotateX valueX1 rotateY valueY1
到 rotateX 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。对所有旋转重复,然后进行任何平移,然后缩放(您必须想象这个)等。
关于javascript - CSS matrix3d 计算不对,但为什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19727790/