我正在尝试通过创建从世界到新旋转的旋转矩阵来旋转三维矢量。我首先围绕Z轴旋转,然后使用右手符号旋转Y轴,最后旋转X轴。
我使用的矩阵可以在维基百科上找到(http://en.wikipedia.org/wiki/Euler_angles)。它位于转换矩阵列表中略低于页面中间的位置。我正在使用ZYX:
我现在使用+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
答案 0 :(得分:1)
ZYX欧拉角旋转矩阵定义为
R_ZYX(dz, dy, dx) = R(Z, dz) * R(Y, dy) * R(X, dx)
有两种不同的方式来读取旋转顺序:从左到右或从右到左。当从左向右读取时,旋转是关于坐标框架的局部轴,正如您正确地执行。只有从从右到左读取时,旋转才是固定坐标系。
现在回答这个问题,如果你想让旋转矢量的所有坐标具有相同的绝对值,让我们计算应旋转的角度dy
。
让r
为v
的长度,让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度是不同的。很难解释,但我希望有所帮助: - )
(编辑:让轴向右转)