矢量的 3D ZYX 旋转

发布于 2024-10-18 20:07:21 字数 915 浏览 1 评论 0原文

我试图通过创建从世界到新旋转的旋转矩阵来在 3 维中旋转向量。我首先使用右手符号绕 Z 轴旋转,然后绕 Y 轴,最后绕 X 轴旋转。

我使用的矩阵可以在维基百科上找到(http://en.wikipedia.org/wiki/Euler_angles< /a>)。它位于变换矩阵列表中页面中间稍下方的位置。我用的是ZYX: 在此处输入图像描述

我现在创建它,Z 轴旋转 +45 度,Y 轴旋转 +45 度,并且没有X 轴旋转。这给出了以下矩阵:

[  0.5   -0.707 0.5   ]
[  0.5    0.707 0.5   ]
[ -0.707  0.0   0.707 ]

现在我将其乘以以下向量:

[ 10 ]
[  0 ]
[  0 ]

可以看出,它是沿 x 轴的 10 个单位长的向量。我预计旋转结果在 x、y 和 z 场中约为 6(z 为负),因为这给出了大约长度为 10 的向量。即,该向量首先在世界 x 和 y 轴之间精确旋转(第一次 z 旋转),然后从那里向下倾斜 45 度,最终恰好位于 xy 平面和负 z 轴之间(第二次 y 旋转)。在我看来,这意味着三个等长的单位向量代表这个向量。

然而,我的矩阵类和所有其他程序都给了我这个向量作为结果:

[  5    ]
[  5    ]
[ -7.07 ]

它看起来是正确的,因为它的长度是预期的 10。那么问题来了,我哪里错了?我确信我在明显的地方犯了一些愚蠢的思想错误,因为它肯定没有三个同样长的手臂:p

I'm trying to rotate a vector in 3 dimensions by creating a rotation matrix from the world to the new rotation. I do the rotation by first rotating around the Z axis, then the Y axis and lastly the X axis using right hand notation.

The matrix I use can be found on wikipedia (http://en.wikipedia.org/wiki/Euler_angles). It's located slightly below the middle of the page in the list of transformation matrices. I'm using the ZYX one:
enter image description here

I now create it with a Z rotation of +45 degrees, a Y rotation of +45 degrees and no X rotation. This gives me the following matrix:

[  0.5   -0.707 0.5   ]
[  0.5    0.707 0.5   ]
[ -0.707  0.0   0.707 ]

Now I multiply it by the following vector:

[ 10 ]
[  0 ]
[  0 ]

As can be seen it's a 10 unit long vector along the x-axis. I expect the rotated result to be around 6 in the x, y, and z field (with z being negative) as that gives a vector of roughly length 10. Ie the vector is rotated first exactly between the world x and y axis (the first z rotation) and then angled down from there another 45 degrees ending up exactly between the x-y plane and the negative z axis (the second y rotation). In my mind this means three equally long unit vectors representing this vector.

However, both my matrix class and all other programs give me this vector as result:

[  5    ]
[  5    ]
[ -7.07 ]

It seems correct as the length of it is 10 as expected. So the question is where am I wrong? I'm sure I'm making some stupid thought error somewhere obvious, because it sure doesn't have three equally long arms :p

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

憧憬巴黎街头的黎明 2024-10-25 20:07:21

ZYX 欧拉角旋转矩阵定义为

R_ZYX(dz, dy, dx) = R(Z, dz) * R(Y, dy) * R(X, dx)

有两种不同的方式读取旋转顺序:从左到右或从右到左。当从左到右读取时,旋转是围绕坐标系的局部轴进行的,正如您正确执行的那样。仅当从从右到左读取时,旋转才会围绕固定坐标系进行。

现在为了回答这个问题,如果您希望旋转矢量的所有坐标都具有相同的绝对值,让我们计算您应该旋转的角度dy

rv 的长度,令a 为绝对坐标值。根据毕索哥拉斯的说法,a^2 + a^2 + a^2 = r^2,因此 a = r / sqrt(3)。旋转矢量相对于 XY 平面的角度为 dy = asin(a / r) = asin(1 / sqrt(3)),约为 35.3 度。该角度与您当前使用的 45 度(或以弧度表示的 asin(1 / sqrt(2)))不同。

测试(使用 Python 和 gameobjects 库):

from gameobjects import *
from math import *
import random

V = vector3.Vector3
T = matrix44.Matrix44

def R_x(dx): return T.x_rotation(dx)
def R_y(dy): return T.y_rotation(dy)
def R_z(dz): return T.z_rotation(dz)

def fmt(v): return "(%.3f, %.3f, %.3f)" % (v[0], v[1], v[2])

dx = 0
dy = asin(1 / sqrt(3.0))
dz = pi / 4

v = V(10, 0, 0)

print "ZYX Euler angle transformations:"
print fmt((R_z(dz) * R_y(dy) * R_x(dx)).transform(v))
dy = pi / 4
print fmt((R_z(dz) * R_y(dy) * R_x(dx)).transform(v))

输出:

ZYX Euler angle transformations:
(5.774, 5.774, -5.774)
(5.000, 5.000, -7.071)

dz = dy = pi / 4 表明该程序与您的欧拉角实现一致。

The ZYX Euler angle rotation matrix is defined as

R_ZYX(dz, dy, dx) = R(Z, dz) * R(Y, dy) * R(X, dx)

There are two different ways of reading the order of the rotations: either from left to right or from right to left. When read from left to right the rotations are about the local axes of the coordinate frame, as you are correctly doing. It's only when read from right to left that the rotations are about a fixed coordinate frame.

Now to answer the question, let's compute the angle dy you should be rotating with if you want all coordinates of the rotated vector to have the same absolute value.

Let r be the length of v and let a be the absolute coordinate value. By Pythogoras, a^2 + a^2 + a^2 = r^2, hence a = r / sqrt(3). The angle of the rotated vector relative to the XY plane is dy = asin(a / r) = asin(1 / sqrt(3)), which is about 35.3 degrees. This angle is different from the 45 degrees (or asin(1 / sqrt(2)) in radians) that you are currently using.

A test (using Python and the gameobjects library):

from gameobjects import *
from math import *
import random

V = vector3.Vector3
T = matrix44.Matrix44

def R_x(dx): return T.x_rotation(dx)
def R_y(dy): return T.y_rotation(dy)
def R_z(dz): return T.z_rotation(dz)

def fmt(v): return "(%.3f, %.3f, %.3f)" % (v[0], v[1], v[2])

dx = 0
dy = asin(1 / sqrt(3.0))
dz = pi / 4

v = V(10, 0, 0)

print "ZYX Euler angle transformations:"
print fmt((R_z(dz) * R_y(dy) * R_x(dx)).transform(v))
dy = pi / 4
print fmt((R_z(dz) * R_y(dy) * R_x(dx)).transform(v))

The output:

ZYX Euler angle transformations:
(5.774, 5.774, -5.774)
(5.000, 5.000, -7.071)

The last line for dz = dy = pi / 4 shows that the program agrees with your Euler angle implementation.

最美不过初阳 2024-10-25 20:07:21

请记住,第二次旋转是相对于轴,而不是向量。在 XY 平面中旋转后,想象整个平面绕 Y 轴扭转 45 度。这与垂直向上扭转旋转矢量(即绕 X=-Y 旋转)直到与 XY 平面成 45 度不同。很难解释,但我希望有所帮助:-)

(编辑:使轴正确旋转)

Remember that the second rotation is relative to the axis, not the vector. After rotating in the XY plane, imagine that whole plane twisting 45 degrees around the Y axis. This is not the same as twisting your rotated vector straight up (i.e. rotating around X=-Y) until it's at 45 degrees to the XY plane. Hard to explain, but I hope that helps :-)

(Edit: got the axes the right way round)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文