【问题标题】:Javascript: issue with 360deg rotations and matrix compositionJavascript:360度旋转和矩阵组合的问题
【发布时间】:2016-06-23 21:24:26
【问题描述】:

我之前询问过正确的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 度角。

请问我该如何解决?

【问题讨论】:

    标签: javascript matrix css-transforms


    【解决方案1】:

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

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

    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:

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

    增加 polyfill 代码中的小数精度可修复此问题。将line 35 从: CSSMatrix.SMALL_NUMBER = 1e-6;

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

    我已经在this fiddle 中修复了这个问题。


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

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

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

    【讨论】:

    • 好的,我已经删除了近似值,现在当添加一个额外的轴时,比如rotateZ,这两个矩阵非常不同。请查看jsfiddle.net/LuL3qoo4/2
    猜你喜欢
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 2016-03-10
    相关资源
    最近更新 更多