来自两个3D点的欧拉角和旋转矩阵

时间:2018-07-27 21:23:46

标签: python matlab euler-angles rotational-matrices

我正在尝试寻找允许在3D空间中从点A转换为点B的欧拉角。

考虑归一化向量A = [1, 0, 0]B = [0.32 0.88 -0.34]

我了解到,通过计算叉积 A × B可以得到旋转轴。 AB之间的角度tan⁻¹(||cross||, A·B)给出,其中A·B是{{ 1}}和A

这给了我旋转矢量B,它是rotvec = [0 0.36 0.93 1.24359531111](叉积被归一化)。

现在我的问题是:我如何从这里移到与从rotvec = [A × B; angle]A 的转换相对应的欧拉角?

在MATLAB中,函数vrrotvec2mat接收旋转矢量作为输入,并输出旋转矩阵。然后,函数rotm2eul应该返回相应的欧拉角。根据{{​​1}}约定,我得到以下结果(以弧度表示):B。但是,这不是预期的结果。

正确答案是[0.2456 0.3490 1.2216],分别对应于XYZ[0 0.3490 1.2216]20°70°的旋转。

当我使用Y(取自hereZ)来验证生成的旋转矩阵时,该矩阵与使用eul2rot([0 0.3490 1.2216])时获得的矩阵不同。

我还有一个Python Spinet,它产生与上述完全相同的结果。

---使用transform3d的Python(2.7)---

eul2rot

我在这里想念的是什么?我应该怎么做?

谢谢

2 个答案:

答案 0 :(得分:4)

旋转矩阵具有3个自由度,但是问题的约束仅限制了其中2个度。

考虑到我们有一个旋转矩阵RA旋转到B从而R*A == B的情况,这可以变得更加具体。如果然后我们构造另一个绕向量RB旋转的旋转矩阵B,则将此旋转应用于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

答案 1 :(得分:1)

我将根据Euler's rotation theorem为您提供解决方案。

此解决方案仅为您提供一个角度,但可以导出其他角度。

import numpy as np


a_vec = np.array([1, 0, 0])/np.linalg.norm(np.array([1, 0, 0]))
b_vec = np.array([0.32, 0.88, -0.34])/np.linalg.norm(np.array([0.32, 0.88, -0.34]))

cross = np.cross(a_vec, b_vec)
ab_angle = np.arccos(np.dot(a_vec,b_vec))


vx = np.array([[0,-cross[2],cross[1]],[cross[2],0,-cross[0]],[-cross[1],cross[0],0]])
R = np.identity(3)*np.cos(ab_angle) + (1-np.cos(ab_angle))*np.outer(cross,cross) + np.sin(ab_angle)*vx


validation=np.matmul(R,a_vec)

这使用公共旋转轴(在这种情况下为特征向量)作为叉积。

则矩阵R为rotation matrix

这是一种通用的实现方式,非常简单。