在 3D 空间中旋转矢量 [英] Rotating a Vector in 3D Space

查看:26
本文介绍了在 3D 空间中旋转矢量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am making an android project in opengl es that uses accelerometer to calculate change in specific axes and my aim is to rotate my spacecraft-like object's movement vector. The problem is that i can't understand the math behind rotation matrices. Default movement vector is 0,1,0 , means +y, so the object looks upward in the beginning. and i am trying to rotate its movement vector so i can move the object where it points. I can gather rotation changes in phone. x-axis : rotate[0], y-axis : rotate[1], z-axis : rotate[2]. How can i rotate my movement vector using rotation matrix ?

推荐答案

如果你想旋转一个向量,你应该构造一个 旋转矩阵.

If you want to rotate a vector you should construct what is known as a rotation matrix.

假设您想将一个向量或一个点旋转 θ,然后 三角学 指出新坐标是

Say you want to rotate a vector or a point by θ, then trigonometry states that the new coordinates are

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

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

To demo this, let's take the cardinal axes X and Y; when we rotate the X-axis 90° counter-clockwise, we should end up with the X-axis transformed into Y-axis. Consider

    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

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

When you understand this, creating a matrix to do this becomes simple. A matrix is just a mathematical tool to perform this in a comfortable, generalized manner so that various transformations like rotation, scale and translation (moving) can be combined and performed in a single step, using one common method. From linear algebra, to rotate a point or vector in 2D, the matrix to be built is

    |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 轴旋转将是

Rotation in 3D

That works in 2D, while in 3D we need to take in to account the third axis. Rotating a vector around the origin (a point) in 2D simply means rotating it around the Z-axis (a line) in 3D; since we're rotating around Z-axis, its coordinate should be kept constant i.e. 0° (rotation happens on the XY plane in 3D). In 3D rotating around the Z-axis would be

    |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:旋转所围绕的轴在矩阵中没有正弦或余弦元素.

Note 1: axis around which rotation is done has no sine or cosine elements in the matrix.

注意 2: 这种执行旋转的方法遵循 欧拉角 轮换系统,简单易学,易掌握.这对于 2D 和简单的 3D 情况非常适用;但是当需要同时围绕所有三个轴进行旋转时,由于该系统的固有缺陷,欧拉角可能不够用,表现为 万向节锁.人们在这种情况下求助于 四元数,这比这更先进,但不会受到正确使用万向节锁.

Note 2: This method of performing rotations follows the Euler angle rotation system, which is simple to teach and easy to grasp. This works perfectly fine for 2D and for simple 3D cases; but when rotation needs to be performed around all three axes at the same time then Euler angles may not be sufficient due to an inherent deficiency in this system which manifests itself as Gimbal lock. People resort to Quaternions in such situations, which is more advanced than this but doesn't suffer from Gimbal locks when used correctly.

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

I hope this clarifies basic rotation.

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

The aforementioned matrices rotate an object at a distance r = √(x² + y²) from the origin along a circle of radius r; lookup polar coordinates to know why. This rotation will be with respect to the world space origin a.k.a revolution. Usually we need to rotate an object around its own frame/pivot and not around the world's i.e. local origin. This can also be seen as a special case where r = 0. Since not all objects are at the world origin, simply rotating using these matrices will not give the desired result of rotating around the object's own frame. You'd first translate (move) the object to world origin (so that the object's origin would align with the world's, thereby making r = 0), perform the rotation with one (or more) of these matrices and then translate it back again to its previous location. The order in which the transforms are applied matters. Combining multiple transforms together is called concatenation or composition.

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

I urge you to read about linear and affine transformations and their composition to perform multiple transformations in one shot, before playing with transformations in code. Without understanding the basic maths behind it, debugging transformations would be a nightmare. I found this lecture video to be a very good resource. Another resource is this tutorial on transformations that aims to be intuitive and illustrates the ideas with animation (caveat: authored by me!).

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

A product of the aforementioned matrices should be enough if you only need rotations around cardinal axes (X, Y or Z) like in the question posted. However, in many situations you might want to rotate around an arbitrary axis/vector. The Rodrigues' formula (a.k.a. axis-angle formula) is a commonly prescribed solution to this problem. However, resort to it only if you’re stuck with just vectors and matrices. If you're using Quaternions, just build a quaternion with the required vector and angle. Quaternions are a superior alternative for storing and manipulating 3D rotations; it's compact and fast e.g. concatenating two rotations in axis-angle representation is fairly expensive, moderate with matrices but cheap in quaternions. Usually all rotation manipulations are done with quaternions and as the last step converted to matrices when uploading to the rendering pipeline. See Understanding Quaternions for a decent primer on quaternions.

这篇关于在 3D 空间中旋转矢量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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