四元数 欧拉角 旋转矩阵
1. 概念
四元数、欧拉角和旋转矩阵都是数学工具,用于描述和处理三维空间中的旋转。它们在计算机图形学、航空航天、机器人学等领域中非常重要。
1.1 欧拉角 (Euler Angles)
定义:
欧拉角是用三个角度来描述物体在三维空间中的旋转。通常这三个角度分别是 俯仰角(Pitch)、偏航角(Yaw) 和 滚转角(Roll)。它们代表绕三个不同轴的旋转。
俯仰角(Pitch):绕水平轴旋转(例如,飞机的机头上升或下降)。
偏航角(Yaw):绕垂直轴旋转(例如,飞机的机头左右转动)。
滚转角(Roll):绕纵轴旋转(例如,飞机的翅膀向上或向下倾斜)。
特点:
直观:欧拉角非常直观,易于理解。比如,坐标系中的物体旋转时,可以直观地通过俯仰、偏航、滚转来描述。
旋转顺序依赖性:不同的旋转顺序会导致不同的结果,旋转顺序(比如先俯仰再偏航)对于结果非常重要。
万向节锁问题:如前面提到的,当物体的某两个旋转轴对齐时,欧拉角可能会出现“万向节锁”问题,即失去自由度,导致无法进行某些旋转。
应用:
直观的场景中常用,尤其是在一些航天、飞行器姿态控制中,欧拉角作为控制和表示姿态的方式非常常见。
1.2 旋转矩阵 (Rotation Matrix)
定义:
旋转矩阵是一种数学工具,用于描述三维空间中的旋转。它是一个 3x3 的矩阵,通过矩阵乘法实现旋转操作。旋转矩阵将一个向量(如物体的坐标)旋转到另一个位置。
如果给定一个旋转矩阵 R 和一个向量 v,旋转后的向量 v’ 可以通过 v’ = R * v 来计算。
特点:
不依赖顺序:旋转矩阵可以通过矩阵乘法组合多个旋转,而且它本身不易出现欧拉角中的“万向节锁”问题。
计算复杂度高:旋转矩阵是 3x3 的矩阵,涉及较多的计算,特别是组合多个旋转时。
易于复合旋转:多个旋转可以通过矩阵乘法进行组合,保持较高的精度。
应用:
在一些需要进行多个旋转合成或需要高精度计算的场景中,旋转矩阵被广泛应用。
例如,在计算机图形学和机器人学中,旋转矩阵经常用于物体的姿态变化。
常见三角函数值
旋转矩阵 绕 x y z 轴 旋转的公式
绕 x-轴旋转,角度为 θ的旋转矩阵是:
绕 y-轴旋转,角度为 θ的旋转矩阵是:
绕 z-轴旋转,角度为 θ的旋转矩阵是:
1.3 四元数 (Quaternions)
定义:
四元数是一种扩展了复数的数学结构,通常用来描述三维空间中的旋转。一个四元数由四个部分组成:一个标量部分和三个虚数部分。它可以表示旋转的轴和角度。
四元数的标准形式是:q=w+xi+yj+zk
其中,w 是标量部分,x、y、z 是虚数部分。四元数不仅能表示旋转,还具有乘法、逆运算等性质,使得旋转的组合更加高效。
四元数与旋转之间的关系是:给定一个单位四元数,它可以用来将一个向量旋转指定的角度。
特点:
避免万向节锁:与欧拉角不同,四元数不会出现万向节锁问题。
计算效率高:四元数的组合非常高效,可以通过四元数的乘法来合成多个旋转。
表示精确:四元数能非常精确地表示旋转,且数值稳定性较好。
表示简洁:四元数只需要四个参数,比旋转矩阵(9个元素)更加节省空间。
应用:
在现代计算机图形学、动画、机器人学、航天等领域,四元数被广泛使用。例如,在3D图形渲染中,四元数用于表示物体的旋转,避免了欧拉角和旋转矩阵的计算复杂度。
四元数还广泛应用于飞行器、航天器的姿态控制系统中,用于实现高效且精确的旋转计算。
1.4 总结
2. 优缺点
2.1 欧拉角
欧拉角通过绕三个坐标轴的旋转(通常是滚转、俯仰、偏航)来描述三维旋转。常见的旋转顺序有:XYZ、ZYX等。
优点:
直观性:欧拉角是人类最自然的旋转方式,很容易理解。比如,飞机的航向(偏航)、俯仰(上仰或下俯)和滚转(左右倾斜)就是典型的欧拉角应用。
易于操作:对角度的直观控制,适用于一些需要精确调整角度的应用。
缺点:
万向节锁(Gimbal Lock):当两个旋转轴对齐时(例如俯仰角为 ±90° 时),会导致一个自由度丢失,使得旋转失去自由度,无法描述某些方向的旋转。
非唯一性:相同的旋转可以通过不同的欧拉角表示出来,可能导致理解上的混淆。
复杂的插值问题:当进行旋转插值(例如旋转动画)时,欧拉角的插值会出现不稳定或者跳跃的情况。
适用场景:
人类可操作的界面:例如飞行模拟器、动画控制等,用户可以通过设置俯仰、偏航、滚转角来调整物体姿态。
工程和机械学:在一些简单的机械控制中,欧拉角由于直观性而被广泛应用。
举个例子:
假设我们有一个飞机模型,它的姿态(也就是它在三维空间中的方向)可以通过 俯仰(pitch)、偏航(yaw) 和 滚转(roll) 来描述。这三个角度就是经典的欧拉角。
俯仰角为 90°(完全上仰)
现在,假设飞机的 俯仰角 达到了 90°,即飞机的机头已经完全朝上(垂直)。此时,飞机的滚转轴和偏航轴已经对齐——两者都指向水平面。在这种情况下:
如果你再试图进行 滚转(绕飞机自身的纵轴旋转),飞机就无法再做左右倾斜的动作,因为滚转轴已经没有了自由度。
如果你再试图进行 偏航(绕垂直轴旋转),也会遇到问题,因为偏航轴和滚转轴已经完全重合,无法再绕垂直轴进行旋转。
这就发生了万向节锁:两个旋转轴(滚转轴和偏航轴)重合,使得飞机的旋转自由度丧失了,不能再绕这两个方向旋转。
没有万向节锁时:飞机可以自由地绕三个独立的轴旋转(俯仰、偏航和滚转),每个角度都有独立的自由度。
发生万向节锁时:当俯仰角达到 90° 时,飞机的滚转轴和偏航轴重合。此时,你只能进行俯仰(上下运动)或绕某个方向的旋转(但不能同时做俯仰和滚转或偏航),导致失去一个自由度。
在三维空间中,假设我们用一个 万向节(gimbal)来描述旋转。万向节由三根轴组成,分别代表俯仰、偏航和滚转。
如果俯仰角为 90°,那么其中两根轴就会重合,导致万向节的两个轴失去独立性。这就造成了 旋转的自由度丧失,也就是我们说的 万向节锁。
2.2 旋转矩阵
旋转矩阵通过一个 3x3 的矩阵来表示三维空间中的旋转。矩阵乘法可以非常方便地实现多个旋转的组合。
优点:
计算简便:旋转矩阵之间的组合(乘法)和插值非常直观,适合矩阵运算的场景。
不受万向节锁影响:旋转矩阵可以描述任意的旋转,而不会受到欧拉角的万向节锁问题。
稳定性:旋转矩阵在数值计算中非常稳定,适合大规模的数值仿真。
缺点:
冗长和难以理解:相比欧拉角和四元数,旋转矩阵更加复杂,包含9个数值,可能不如其他方法直观。
存储空间:需要9个浮点数来表示一个旋转,相比四元数的4个数值占用更多空间。
计算量大:矩阵运算需要更高的计算量,尤其是在高频率旋转和实时系统中,可能会导致性能瓶颈。
适用场景:
计算机图形学:在图形渲染和变换中,旋转矩阵经常用于将顶点从一个坐标系变换到另一个坐标系。
机器人学:机器人运动学和路径规划中,旋转矩阵用于描述机器人末端执行器的姿态。
物理仿真:例如在刚体动力学中,旋转矩阵用于处理物体的旋转运动。
2.3 四元数
四元数是由一个标量(w)和三个向量部分(x, y, z)组成的四元数结构,可以有效表示三维旋转。四元数在计算旋转时避免了万向节锁问题,且计算更为高效。
优点:
避免万向节锁:四元数能稳定地表示任意三维旋转,避免了欧拉角的万向节锁问题。
高效的插值:四元数在进行旋转插值时(如球面线性插值 SLERP)非常稳定,常用于动画和模拟中的平滑旋转。
较少的计算开销:与旋转矩阵相比,四元数在旋转组合时通常更为高效,因为它只需要四个数值。
更少的存储需求:四元数只需要 4 个数值,比旋转矩阵(9 个数值)更节省内存。
缺点:
不直观:四元数的物理意义不像欧拉角那样直观。它不容易被人类直观理解,因此在调试和交互式控制中可能不如欧拉角友好。
需要额外的转换:在一些应用中(如与用户交互时),需要将四元数转换回欧拉角或旋转矩阵来解释或显示旋转。
适用场景:
计算机图形学:四元数在3D图形的动画和旋转中应用广泛,尤其是在需要平滑旋转插值的场景中(如虚拟现实、视频游戏中的角色动画)。
物理模拟:在物理仿真中,四元数用于稳定的旋转表示和高效计算。
航天航空:在航天器的姿态控制中,四元数被广泛使用,因为它们能够避免万向节锁并提供高效的旋转计算。
3. 相互转换
3.1 欧拉角到旋转矩阵
欧拉角是通过三个角度来描述旋转的方式,通常表示为绕三个坐标轴的旋转:俯仰角(pitch)、偏航角(yaw)和滚转角(roll)。不同的旋转顺序会得到不同的旋转矩阵。常见的旋转顺序有 ZYX 顺序(绕 Z 轴旋转,然后绕 Y 轴,最后绕 X 轴旋转)。
欧拉角到旋转矩阵(ZYX顺序)
给定绕 Z 轴、Y 轴和 X 轴的旋转角度,旋转矩阵为:
绕 Z 轴的旋转矩阵:
绕 Y 轴的旋转矩阵:
绕 X 轴的旋转矩阵:
3.2 旋转矩阵到欧拉角
从旋转矩阵恢复欧拉角的方法相对复杂,但可以通过以下公式计算。假设旋转矩阵 R
R 是 3x3 矩阵:
俯仰角 θ
θ(绕 Y 轴旋转):
偏航角 ψ
ψ(绕 Z 轴旋转):
滚转角 ϕ
ϕ(绕 X 轴旋转):
3.3 四元数到旋转矩阵
四元数q=w+xi+yj+zk 用来表示旋转,其中w 是标量部分,x,y,z 是向量部分。四元数到旋转矩阵的转换公式如下:
假设四元数 q=(w,x,y,z),旋转矩阵 R 为:
3.4 旋转矩阵到四元数
如果你有旋转矩阵 R,你可以从中恢复四元数 q=(w,x,y,z)。具体计算方法如下:
计算 w:
计算 x、y、z:
3.5 四元数到欧拉角
从四元数 q=(w,x,y,z) 到欧拉角的转换,可以使用以下公式:
俯仰角θ:
偏航角ψ:
滚转角ϕ:
3.6 欧拉角到四元数
从欧拉角 ϕ,θ,ψ(滚转、俯仰、偏航)到四元数的转换公式如下:q=(w,x,y,z)
其中:
4. 代码转换
transforms3d 是一个 Python 库,可以帮助进行这些不同旋转表示之间的转换。下面是如何使用 transforms3d 进行欧拉角、旋转矩阵和四元数之间的相互转换。
如果你还没有安装 transforms3d,可以通过 pip 安装:
pip install transforms3d
4.1 欧拉角到旋转矩阵
假设有一个欧拉角 euler(以弧度为单位),可以使用 transforms3d 中的 euler2mat 函数来得到旋转矩阵:
import transforms3d as t3d
import numpy as np
# 假设欧拉角是绕X, Y, Z轴的旋转
euler_angles = np.radians([30, 45, 60]) # 例如 30°,45°,60°绕X, Y, Z轴旋转
# 转换为旋转矩阵
rotation_matrix = t3d.euler.euler2mat(*euler_angles)
print("Rotation Matrix:")
print(rotation_matrix)
4.2 欧拉角到四元数
可以使用 euler2quat 来将欧拉角转换为四元数:
# 欧拉角到四元数
quaternion = t3d.euler.euler2quat(*euler_angles)
print("Quaternion:")
print(quaternion)
4.3 旋转矩阵到欧拉角
如果已经有了一个旋转矩阵,使用 mat2euler 函数可以将其转换为欧拉角:
# 旋转矩阵到欧拉角
euler_from_matrix = t3d.euler.mat2euler(rotation_matrix)
print("Euler Angles (radians):")
print(euler_from_matrix)
4.4 旋转矩阵到四元数
可以使用 mat2quat 将旋转矩阵转换为四元数:
# 旋转矩阵到四元数
quaternion_from_matrix = t3d.quaternions.mat2quat(rotation_matrix)
print("Quaternion from Matrix:")
print(quaternion_from_matrix)
4.5 四元数到欧拉角
如果有一个四元数,使用 quat2euler 可以将其转换为欧拉角:
# 四元数到欧拉角
euler_from_quat = t3d.euler.quat2euler(quaternion)
print("Euler Angles from Quaternion (radians):")
print(euler_from_quat)
4.6 四元数到旋转矩阵
最后,使用 quat2mat 可以将四元数转换为旋转矩阵:
# 四元数到旋转矩阵
matrix_from_quat = t3d.quaternions.quat2mat(quaternion)
print("Rotation Matrix from Quaternion:")
print(matrix_from_quat)
4.7 总结
欧拉角 -> 旋转矩阵: euler2mat
欧拉角 -> 四元数: euler2quat
旋转矩阵 -> 欧拉角: mat2euler
旋转矩阵 -> 四元数: mat2quat
四元数 -> 欧拉角: quat2euler
四元数 -> 旋转矩阵: quat2mat
在进行这些转换时,注意欧拉角通常使用弧度表示,因此需要使用 np.radians 和 np.degrees 来在度和弧度之间进行转换