【问题标题】:Understanding the math behind rotating around an arbitrary axis in WebGL了解 WebGL 中围绕任意轴旋转背后的数学原理
【发布时间】:2014-03-30 15:35:56
【问题描述】:

最近,我一直在研究一些用于 WebGL 的矩阵库,以更好地理解在矩阵上执行的各种变换的数学运算。目前,我正在尝试更好地理解用于旋转变换的数学。

具体来说,我已经了解了用于围绕三个轴旋转的变换以及如何生成这些矩阵(如下所示)。

但是,我没有得到用于围绕不是 x、y 或 z 轴的任意轴旋转的方程。

我目前正在阅读WebGL Programming Guide,在提供的库中,他们使用以下JS 围绕任意轴旋转(其中e 是包含4x4 矩阵的数组):

len = Math.sqrt(x*x + y*y + z*z);
if (len !== 1) {
  rlen = 1 / len;
  x *= rlen;
  y *= rlen;
  z *= rlen;
}
nc = 1 - c;
xy = x * y;
yz = y * z;
zx = z * x;
xs = x * s;
ys = y * s;
zs = z * s;

e[ 0] = x*x*nc +  c;
e[ 1] = xy *nc + zs;
e[ 2] = zx *nc - ys;
e[ 3] = 0;

e[ 4] = xy *nc - zs;
e[ 5] = y*y*nc +  c;
e[ 6] = yz *nc + xs;
e[ 7] = 0;

e[ 8] = zx *nc + ys;
e[ 9] = yz *nc - xs;
e[10] = z*z*nc +  c;
e[11] = 0;

e[12] = 0;
e[13] = 0;
e[14] = 0;
e[15] = 1;

据我所知,代码的第一部分用于规范化 3D 矢量,但除此之外,我真的无法理解它。
例如,ncxyyzzxxsyszs 是什么意思?另外,举个例子,他们是怎么想出公式x*x*nc + c来计算e[0]的?

根据related SO post,我确实找到了对以下矩阵的引用,用于绕任意轴旋转:

这似乎与上面的 JS 代码正在做的事情有关(如果不一样的话)。

这个矩阵是如何生成的?关于如何围绕任意轴旋转,我想了很多,但我唯一能想到的是将从原点延伸的 3D 矢量分解为其 x、y 和 z 分量,然后执行三个不同的旋转,这似乎效率很低。

让一个矩阵为您完成所有这些似乎是最好的,但我真的很想了解该矩阵以及它是如何生成的。

最后,虽然我不确定,但上面的矩阵似乎没有考虑轴从原点的平移。这是否可以通过简单地使用 4x4 矩阵而不是在适当位置使用 Tx、Ty 和 Tz 值来轻松处理?

谢谢。

【问题讨论】:

    标签: matrix rotation webgl javascript


    【解决方案1】:

    请在此处找到数学概述:

    http://paulbourke.net/geometry/rotate/

    这里有详细解释:

    http://web.archive.org/web/20140515121518/http://inside.mines.edu:80/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.html

    关于不考虑平移的旋转矩阵是正确的。

    是的,您可以通过将平移 x 旋转相乘来创建旋转后平移矩阵:

        1 0 0 t1      r11 r12 r13 0
    T = 0 1 0 t2  R = r21 r22 r23 0
        0 0 1 t3      r31 r32 r33 0
        0 0 0 1       0   0   0   1
    
            1 0 0 t1   r11 r12 r13 0   r11 r12 r13 t1
    T x R = 0 1 0 t2 x r21 r22 r23 0 = r21 r22 r23 t2
            0 0 1 t3   r31 r32 r33 0   r31 r32 r33 t3
            0 0 0 1    0   0   0   1   0   0   0   1
    

    如果您只想绕远离原点的任意轴(即绕线)旋转,请在第二个 URL (http://web.archive.org/web/20140515121518/http://inside.mines.edu:80/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.html) 中查找“6.2 绕任意线旋转的归一化矩阵”项.

    【讨论】:

    • 它解释了复数矩阵是 7 个矩阵 (T-1 Rx-1 Ry-1 Rz Ry Rx T) 的乘积,但它没有显示完整的数学。你可以在这里找到更详细的数学:inside.mines.edu/~gmurray/ArbitraryAxisRotation/…
    • 考虑完整的变换(Txz^-1 Tz^-1 Rz(θ) Tz Txz)。 Rz(θ) 表示矩阵围绕 z 轴旋转 θ。这是第 3 节中的矩阵 Rz(γ),而参数 θ 是围绕任意轴 (u,v,w) 的期望旋转。诀窍是在 Rz(θ) 之前的复合变换——在 Rz(θ) 右侧相乘的矩阵——移动空间以使任意轴 (u,v,w) 与轴 Z ( 0,0,1)。然后Rz(θ)可以用来绕它旋转θ。
    • 1) 请注意: 4.1 Txz :使用 Rz 以及从轴矢量分量 (u,v,w) 计算的 sin 和 cos 4.2 Tz :使用 Ry 以及从轴矢量分量计算的 sin 和 cos (u,v,w) 2) 如何求逆矩阵:mathsisfun.com/algebra/matrix-inverse.html
    • 3) 不,作者使用了正确的顺序。当您将组合变换矩阵应用于向量/点(即行矩阵)时,您会发现效果就像从右侧(最后一个矩阵)到左侧(第一个矩阵)开始应用每个单独的变换。
    • 4) 表示使用了绕轴旋转的矩阵,但是为了获得正弦和余弦,作者更喜欢使用旋转轴分量而不是玩反三角函数(en.wikipedia.org/wiki/Inverse_trigonometric_functions) ;我认为这是因为逆三角在计算上是昂贵的(当然在这种情况下存在选项)。 5) 是的,关键是将旋转轴与 Z 对齐,但如果旋转轴开始已经与 z 对齐,则这些矩阵将不起作用。
    【解决方案2】:

    如果你是围绕角度 theta 旋转,那么在代码中:

    c = cos(theta);
    nc = 1-cos(theta); // (or 1-c)
    s = sin(theta);
    

    所以在代码中,

    x 就是 ux

    xy 就是 uxuy

    xs 就是 uxsinθ

    等等。所以,在公式中,第一行的第三个表达式,即 uxuz(1-cosθ) + uysinθ变成 zx * nc - ys

    考虑到这一点,您可以看到代码只是 R 公式的表达式,除了代码将其表示为 4x4 矩阵而不是 3x3。第 4 维用于平移,但表达式指定在所有三个方向上的平移为零。

    【讨论】:

    • 这实际上对理解所有数学符号如何转换为变量非常有帮助。谢谢。
    • 代码与提供的公式的不同之处在于反转使用 sin(theta) 的每个术语的符号。所以 zx * nc - ys 实际上应该是 zx * nc + ys。它实际上是负 theta 的公式。这是因为 sine(-theta) = -sine(theta) 和 cosine(-theta) = cosine(theta) 所以你可以说代码的旋转方向与公式相反。
    • 了解也非常有帮助。是否有任何理由以一种方式而不是另一种方式做事,还是完全任意并由编码人员决定采用哪种方式?谢谢。
    • 旋转方向完全由编码器决定。但是该公式可能是为标准坐标系编写的,其中 y 随着您的上升而增加。但是许多绘图实现(例如 java Graphics 对象)随着您的下降而增加 y。所以这也会反转旋转方向。所以编写代码可能是为了弥补这一点。
    • 非常有趣。我从你的解释中学到了很多。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多