69

我正在opengl es中制作一个android项目,它使用加速度计来计算特定轴的变化,我的目标是旋转我的航天器状物体的运动矢量。问题是我无法理解旋转矩阵背后的数学。默认移动向量是 0,1,0 ,表示 +y,所以对象一开始向上看。我正在尝试旋转它的运动矢量,这样我就可以移动它指向的对象。我可以收集手机中的旋转变化。x轴:旋转[0],y轴:旋转[1],z轴:旋转[2]。如何使用旋转矩阵旋转我的运动矢量?

4

2 回答 2

215

如果要旋转矢量,则应构造所谓的旋转矩阵

二维旋转

假设你想将一个向量或一个点旋转 θ,然后三角函数表明新坐标是

    x' = x cos θ − y sin θ
    y' = x sin θ + y cos θ

为了演示这一点,让我们以基本轴 X 和 Y 为例;当我们将 X 轴逆时针旋转 90° 时,我们应该最终将 X 轴转换为 Y 轴。考虑

    Unit vector along X axis = <1, 0>
    x' = 1 cos 90 − 0 sin 90 = 0
    y' = 1 sin 90 + 0 cos 90 = 1
    New coordinates of the vector, <x', y'> = <0, 1>  ⟹  Y-axis

当您了解这一点时,创建一个矩阵来执行此操作就变得简单了。矩阵只是一种数学工具,可以以一种舒适、通用的方式执行此操作,因此可以使用一种常用方法在一个步骤中组合和执行各种变换,如旋转、缩放和平移(移动)。从线性代数,旋转二维点或向量,要建立的矩阵是

    |cos θ   −sin θ| |x| = |x cos θ − y sin θ| = |x'|
    |sin θ    cos θ| |y|   |x sin θ + y cos θ|   |y'|

3D 旋转

这在 2D 中有效,而在 3D 中我们需要考虑第三轴。在 2D 中围绕原点(一个点)旋转矢量仅意味着在 3D 中围绕 Z 轴(一条线)旋转它;因为我们围绕 Z 轴旋转,所以它的坐标应该保持不变,即 0°(旋转发生在 3D 中的 XY 平面上)。在 3D 中围绕 Z 轴旋转将是

    |cos θ   −sin θ   0| |x|   |x cos θ − y sin θ|   |x'|
    |sin θ    cos θ   0| |y| = |x sin θ + y cos θ| = |y'|
    |  0       0      1| |z|   |        z        |   |z'|

围绕 Y 轴将是

    | cos θ    0   sin θ| |x|   | x cos θ + z sin θ|   |x'|
    |   0      1       0| |y| = |         y        | = |y'|
    |−sin θ    0   cos θ| |z|   |−x sin θ + z cos θ|   |z'|

围绕 X 轴将是

    |1     0           0| |x|   |        x        |   |x'|
    |0   cos θ    −sin θ| |y| = |y cos θ − z sin θ| = |y'|
    |0   sin θ     cos θ| |z|   |y sin θ + z cos θ|   |z'|

注 1:旋转所围绕的轴在矩阵中没有正弦或余弦元素。

注2:这种旋转方式遵循欧拉角旋转系统,教简单易掌握。这对于 2D 和简单的 3D 案例非常有效;但是当需要同时围绕所有三个轴进行旋转时,由于该系统的固有缺陷(表现为万向节锁定),欧拉角可能不够。人们在这种情况下使用Quaternion s,它比这更先进,但在正确使用时不会受到 Gimbal 锁的影响。

我希望这能澄清基本的轮换。

自转不是公转

上述矩阵在距离原点 r = √(x² + y²) 处沿半径为 r 的圆旋转物体;查找极坐标以了解原因。这种旋转将相对于世界空间原点又名革命。通常我们需要围绕它自己的框架/枢轴旋转一个对象,而不是围绕世界,即本地原点。这也可以看作是 r = 0 的特殊情况。由于并非所有对象都位于世界原点,因此仅使用这些矩阵进行旋转不会产生围绕对象自身框架旋转的预期结果。你先翻译(移动)对象到世界原点(以便对象的原点与世界的原点对齐,从而使 r = 0),使用这些矩阵中的一个(或多个)执行旋转,然后将其再次转换回其先前的位置。应用变换的顺序很重要。将多个变换组合在一起称为串联组合

作品

我敦促您阅读有关线性和仿射变换及其组合的信息,以便一次性执行多个变换,然后再在代码中进行变换。如果不了解其背后的基本数学原理,调试转换将是一场噩梦。我发现这个讲座视频是一个非常好的资源。另一个资源是这个关于转换的教程,旨在直观并用动画说明想法(警告:由我创作!)。

围绕任意向量旋转

如果您只需要像发布的问题中那样围绕基本轴(X、Y 或 Z)旋转,上述矩阵的乘积就足够了。但是,在许多情况下,您可能希望围绕任意轴/矢量旋转。罗德里格斯公式(又名轴角公式)是该问题的常用解决方案。但是,仅当您只使用向量和矩阵时才使用它。如果您使用的是四元数,只需构建一个具有所需矢量和角度的四元数。四元数是存储和操作 3D 旋转的绝佳选择;它很紧凑快速,例如在轴角表示中连接两个旋转相当昂贵,矩阵适中但四元数便宜。通常所有的旋转操作都是使用四元数完成的,并且在上传到渲染管道时作为最后一步转换为矩阵。请参阅了解四元数以获得有关四元数的良好入门。

于 2013-01-30T17:02:19.227 回答
0

我推断你的向量的 X 分量应该是 M*cos(o) cos(t)+x,Y 分量应该是 M cos(t) sin(o)+y,z 分量应该是 M cos(o )*sin(t)+z 其中 M 是向量的大小,o 是在垂直平面中的旋转角度,t 是在水平平面中的旋转角度,x 是旋转中心的 x 值,y 是旋转中心的 y 值,z 是旋转中心的 z 值。请告诉我这是否适合您。

于 2021-03-16T13:09:22.673 回答