Javascript:360度旋转和矩阵组成的问题 [英] Javascript: issue with 360deg rotations and matrix composition

查看:107
本文介绍了Javascript:360度旋转和矩阵组成的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前曾问过有关透视功能的正确用法(计算和组成矩阵),现在我遇到了一个较旧的问题,而且我并不希望这仍然是一个大问题.

I asked previously about the proper function for perspective (to compute and compose a matrix), now I'm facing an older problem and I wasn't expecting this to be so much of an issue still.

基本上360度/720度只是零,我不知道如何破解以下功能来解决该问题.

Basically 360deg / 720deg is just zero and I don't know how to hack the following function to fix that.

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)的计算转换中得出.

When using 360deg rotations (on any axis) to compose a matrix, the CSSMatrix.rotate() method is creating a rotation matrix and for each angle value we get angle * Math.PI / 180 then other sinus / cosinus operations, but the matrix result is different from a computed transform of a regular rotateX(360deg).

在此处查看我的小提琴,其中相同的代码不能正常工作并具有360度角度和工作正常,其角度不同于360度.

See my fiddles here where same code doesn't work properly with 360deg angle and working properly with angles different from 360deg.

我该如何解决?

推荐答案

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

The issue here is the precision supported by the CSSMatrix polyfill's code. It supports upto 6 decimals and truncates any lesser value (positive or negative) to 0 i.e. anything less than 0.000001 will be converted to 0.

在您的小提琴中,如果仅应用rotateX(360deg)转换,它将转换为此matrix3d:

In your fiddle, if you just apply the rotateX(360deg) transform, it converts to this matrix3d:

matrix3d(1,0,0,0,0,1,-2.44929e-16,0,0,2.44929e-16,1,0,0,0,0,1)

matrix3d(1, 0, 0, 0, 0, 1, -2.44929e-16, 0, 0, 2.44929e-16, 1, 0, 0, 0, 0, 1)

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

The polyfill converts -2.44929e-16 and 2.44929e-16 to 0 thereby generating this matrix3d:

matrix3d(1、0、0、0、0、1、0、0、0、0、1、0、0、0、0、1)

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

增加polyfill代码中的小数精度可以解决此问题.将第35行从以下位置更改: CSSMatrix.SMALL_NUMBER = 1e-6;

Increasing the decimal precision in the polyfill's code fixes this issue. Change line 35 from: CSSMatrix.SMALL_NUMBER = 1e-6;

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

我已在小提琴中修复了该问题.

I've fixed that in this fiddle.

关于注释中有关沿2轴旋转时生成不同矩阵的问题:这是因为小提琴中使用的compose函数同时沿所有轴施加旋转-这等效于一个rotate3d(x, y, z)调用.

Regarding the question in the comment about different matrices being generated when applying rotate along 2 axes: This is because the compose function used in the fiddle applies rotation along all axes at the same time - which would be equivalent to a single rotate3d(x, y, z) call.

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

But the transforms applied via CSS in the fiddle rotate on the X and Z axes separately which would be equivalent to applying rotate(x, 0, 0) followed by rotate(0, 0, z).

可以通过更改小提琴中的compose函数,并将polyfill生成的matrix3d与浏览器生成的matrix3d进行比较来验证这一点.

This can be verified by changing the compose function in the fiddle and comparing the matrix3d generated by the polyfill vs the one generated by the browser.

这篇关于Javascript:360度旋转和矩阵组成的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆