矢量的3D Z-Y-X旋转

时间:2011-02-22 17:51:42

标签: 3d matrix rotation

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

我使用的矩阵可以在维基百科上找到(http://en.wikipedia.org/wiki/Euler_angles)。它位于转换矩阵列表中略低于页面中间的位置。我正在使用ZYX: enter image description here

我现在使用+45度的Z旋转,+ 45度的Y旋转并且没有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

2 个答案:

答案 0 :(得分:1)

ZYX欧拉角旋转矩阵定义为

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

有两种不同的方式来读取旋转顺序:从左到右或从右到左。当从左向右读取时,旋转是关于坐标框架的局部轴,正如您正确地执行。只有从从右到左读取时,旋转才是固定坐标系。

现在回答这个问题,如果你想让旋转矢量的所有坐标具有相同的绝对值,让我们计算旋转的角度dy

rv的长度,让a为绝对坐标值。由Pythogoras,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的最后一行表明该程序与您的Euler角度实现一致。

答案 1 :(得分:0)

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

(编辑:让轴向右转)