首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在三维空间中旋转矢量

在三维空间中旋转矢量
EN

Stack Overflow用户
提问于 2013-01-30 23:31:42
回答 2查看 208.8K关注 0票数 66

我正在用opengl es做一个android项目,它使用加速计来计算特定轴的变化,我的目标是旋转我的航天器般的物体的运动矢量。问题是我不能理解旋转矩阵背后的数学原理。默认移动向量为0,1,0,表示+y,因此对象在开始时向上看。我试着旋转它的运动矢量,这样我就可以把物体移动到它指向的地方。我可以在手机中收集轮换的变化。X轴:旋转,y轴: rotate1,z轴: rotate2。如何使用旋转矩阵旋转我的移动矢量?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-31 01:02:19

如果你想旋转一个向量,你应该构造一个称为rotation matrix的东西。

在二维中旋转

假设您想要按θ旋转一个向量或一个点,然后trigonometry声明新坐标为

代码语言:javascript
复制
    x' = x cos θ − y sin θ
    y' = x sin θ + y cos θ

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

代码语言:javascript
复制
    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

当你理解了这一点,创建一个矩阵来做这件事就变得很简单了。矩阵只是一种数学工具,以一种舒适的、通用的方式执行此操作,以便可以使用一种常见的方法在单个步骤中组合和执行各种变换,如旋转、缩放和平移(移动)。在线性代数中,要在2D中旋转点或向量,要构建的矩阵为

代码语言:javascript
复制
    |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轴旋转将是

代码语言:javascript
复制
    |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轴周围将是

代码语言:javascript
复制
    | 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轴的方向是

代码语言:javascript
复制
    |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:这种执行旋转的方法遵循Euler angle旋转系统,该系统简单易学,易于掌握。这对于2D和简单的3D情况工作得很好;但是当需要同时围绕所有三个轴执行旋转时,由于该系统中的固有缺陷(表现为Gimbal lock ),欧拉角可能不够。在这种情况下,人们求助于Quaternions,它比这更高级,但在正确使用时不会受到万向锁定的影响。

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

旋转而不是旋转

上述矩阵沿半径为r的圆以距离r=√(x²+ y²)的距离旋转对象;请查看polar coordinates以了解原因。这一自转将是相对于世界空间起源的一次革命。通常,我们需要围绕对象自己的框架/轴心旋转,而不是围绕世界的局部原点。这也可以看作是r= 0的特殊情况。由于并非所有对象都位于世界原点,因此简单地使用这些矩阵旋转不会产生围绕对象自身的帧旋转所需的结果。首先将对象translate (移动)到世界原点(以便对象的原点与世界原点对齐,从而使r= 0),使用这些矩阵中的一个(或多个)执行旋转,然后将其再次平移回以前的位置。变换在matters中的应用顺序。将多个变换组合在一起称为拼接或合成。

作文

我强烈建议您阅读有关线性和仿射变换及其组合的知识,以便在代码中使用变换之前一次执行多个变换。如果不了解它背后的基本数学原理,调试转换将是一场噩梦。我发现this lecture video是一个非常好的资源。另一个资源是this tutorial on transformations,它旨在变得直观,并用动画说明想法(注意:作者是我!)。

围绕任意向量旋转

如果你只需要围绕主轴(X,Y或Z)旋转,那么上述矩阵的乘积就足够了,就像张贴的问题一样。但是,在许多情况下,您可能希望围绕任意轴/向量旋转。Rodrigues' formula (也称为轴角公式)是解决此问题的常用方法。但是,只有当您只能使用向量和矩阵时,才可以使用它。如果您使用的是Quaternions,只需使用所需的向量和角度构建一个四元数。四元数是存储和操作3D旋转的优秀替代方案;它紧凑而快速,例如,在轴角表示中连接两个旋转相当昂贵,对于矩阵来说中等,但在四元数中很便宜。通常,所有旋转操作都是用四元数完成的,作为最后一步,在上载到渲染管道时会转换为矩阵。有关四元数的入门读物,请参阅Understanding Quaternions

票数 208
EN

Stack Overflow用户

发布于 2021-03-16 21:09:23

我已经推导出向量的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值。请告诉我这对你是否有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14607640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档