我试图找到允许在 3D 空间中从点 A
到点 B
的转换的欧拉角。
考虑归一化向量 A = [1, 0, 0]
和 B = [0.32 0.88 -0.34]
。
我知道通过计算叉积 A × B
我得到了旋转轴。 A
和 B
之间的角度 由 tan⁻¹(||cross||, A·B)
,其中 A·B
是 A
和 B
之间的点积。
这给了我旋转矢量 rotvec = [0 0.36 0.93 1.24359531111]
,即 rotvec = [A × B; angle]
(叉积被归一化)。
现在我的问题是:我如何从这里移动到对应于从 A
到 B
的转换的欧拉角?
在 MATLAB 中,函数 vrrotvec2mat 接收一个旋转向量作为输入并输出一个旋转矩阵。然后函数 rotm2eul 应该返回相应的欧拉角。我得到以下结果(以弧度为单位):[0.2456 0.3490 1.2216]
,根据 XYZ
约定。然而,这不是预期的结果。
正确答案是 [0 0.3490 1.2216]
,对应于 Y< 中的
和 20°
和 70°
旋转Z
。
当我使用 eul2rot([0 0.3490 1.2216])
(使用 eul2rot
取自 here )来验证生成的旋转矩阵时,这个与我的不同使用vrrotvec2mat(rotvec)
时获取。
我还有一个 Python spinet,它产生与上述完全相同的结果。
--- Python (2.7) 使用 transform3d ---
import numpy as np
import transforms3d
cross = np.cross(A, B)
dot = np.dot(A, B.transpose())
angle = math.atan2(np.linalg.norm(cross), dot)
rotation_axes = sklearn.preprocessing.normalize(cross)
rotation_m = transforms3d.axangles.axangle2mat(rotation_axes[0], angle, True)
rotation_angles = transforms3d.euler.mat2euler(rotation_m, 'sxyz')
我在这里缺少什么?我应该怎么做?
谢谢
最佳答案
旋转矩阵有 3 个自由度,但您的问题的约束只限制了其中的 2 个自由度。
考虑到我们有一个从 A
旋转到 B
的旋转矩阵 R
的情况,这可以变得更具体,所以 R*A == B
。如果我们然后构造另一个围绕向量 B
旋转的旋转矩阵 RB
然后将此旋转应用于 R*A
将不会有任何效果,即B == R*A == RB*R*A
。但是,它将产生具有不同欧拉角的不同旋转矩阵 RB*R
。
这是 MATLAB 中的示例:
A = [1; 0; 0];
B = [0.32; 0.88; -0.34];
A = A / norm(A);
B = B / norm(B);
ax = cross(A, B);
ang = atan2(norm(ax), dot(A, B)); % ang = acos(dot(A, B)) works too
R = axang2rotm([ax; ang].');
ang_arbitrary = rand()*2*pi;
RB = axang2rotm([B; ang_arbitrary].');
R*A - B
RB*R*A - B
rotm2eul(R)
rotm2eul(RB*R)
结果
ans =
1.0e-15 *
-0.0555
0.1110
0
ans =
1.0e-15 *
0.2220
0.7772
-0.2776
ans =
1.2220 0.3483 0.2452
ans =
1.2220 0.3483 0.7549
关于python - 来自两个 3D 点的欧拉角和旋转矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51565760/