Javascript:360deg旋转和矩阵组合的问题

时间:2016-03-09 13:16:46

标签: javascript matrix css-transforms

我之前曾问过适当的function for perspective(计算和编写矩阵),现在我面临的是一个较旧的问题,我并不认为这仍然是一个很大的问题。

基本上360deg / 720deg只是零,我不知道如何破解以下功能来解决这个问题。

CSSMatrix.Rotate = function(rx, ry, rz){
 rx *= Math.PI / 180;
 ry *= Math.PI / 180;
 rz *= Math.PI / 180;

 // minus sin() because of right-handed system
 var cosx = Math.cos(rx), sinx = - Math.sin(rx);
 var cosy = Math.cos(ry), siny = - Math.sin(ry);
 var cosz = Math.cos(rz), sinz = - Math.sin(rz);
 var m = new CSSMatrix();

 m.m11 = m.a = cosy * cosz;
 m.m12 = m.b = -cosy * sinz;
 m.m13 = siny;

m.m21 = m.c = sinx * siny * cosz + cosx * sinz;
m.m22 = m.d = cosx * cosz - sinx * siny * sinz;
m.m23 = - sinx * cosy;

 m.m31 = sinx * sinz - cosx * siny * cosz;
 m.m32 = sinx * cosz + cosx * siny * sinz;
 m.m33 = cosx * cosy;

 return m;
};

当使用360度旋转(在任何轴上)构成矩阵时,CSSMatrix.rotate()方法正在创建一个旋转矩阵,对于每个角度值,我们得到angle * Math.PI / 180然后是其他正弦/余弦运算,但是矩阵结果不同于常规rotateX(360deg)的计算变换。

在这里查看我的小提琴,其中相同的代码doesn't work properly具有360度角度和working properly,其角度与360度不同。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

此处的问题是CSSMatrix polyfill代码支持的精度。它支持最多6位小数并将任何较小的值(正或负)截断为0,即小于0.000001的任何值都将转换为0.

在你的小提琴中,如果你只是应用rotateX(360deg)变换,它会转换为这个matrix3d:

  

matrix3d(1,0,0,0,0,1,-2.44929e-16,0,0,2。244929e-16,1,0,0,0,1,1)

polyfill将-2.44929e-162.44929e-16转换为0,从而生成此matrix3d:

  

matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)

增加polyfill代码中的小数精度可以解决此问题。从{更改line 35CSSMatrix.SMALL_NUMBER = 1e-6;

CSSMatrix.SMALL_NUMBER = 1e-20; // 20 decimal point precision

我已经在this小提琴中解决了这个问题。

编辑:关于在沿2轴应用旋转时生成的不同矩阵的注释中的问题:这是因为小提琴中使用的compose函数同时沿所有轴应用旋转 - 这将是相当于一个rotate3d(x, y, z)电话。

但是通过CSS在小提琴中应用的变换分别在X和Z轴上旋转,这相当于应用rotate(x, 0, 0)后跟rotate(0, 0, z)

这可以通过更改小提琴中的compose函数并比较polyfill生成的matrix3d与浏览器生成的matrix3d来验证。