一.四元数(Quaternion)中四个分量的含义
四元数是一种用于表示3D旋转的数学工具,由四个分量组成,通常表示为 (x, y, z, w) 或 (i, j, k, real)。在Three.js中,THREE.Quaternion类使用(x, y, z, w)的表示形式。
四个分量的详细解释
- 
虚部 (x, y, z):
- 
表示旋转轴的方向向量
 - 
这个向量会被自动规范化(长度为1)
 - 
分量的比例决定了旋转轴的方向
 - 
例如:(1, 0, 0)表示X轴,(0, 1, 0)表示Y轴
 
 - 
 - 
实部 (w):
- 
表示旋转的角度(实际上是角度的一半的余弦值)
 - 
与虚部共同决定旋转量
 - 
当w=1时表示无旋转(单位四元数)
 
 - 
 
数学关系
四元数可以表示为:
            
            
              javascript
              
              
            
          
          q = [x, y, z, w] = [sin(θ/2)*axis_x, sin(θ/2)*axis_y, sin(θ/2)*axis_z, cos(θ/2)]
        其中:
- 
θ 是旋转角度
 - 
axis_x, axis_y, axis_z\] 是旋转轴的单位向量
 
- 
无旋转的单位四元数
javascriptnew THREE.Quaternion(0, 0, 0, 1) 
2.绕Y轴旋转90度:
            
            
              javascript
              
              
            
          
          // 旋转轴:(0, 1, 0)
// 旋转角度:π/2 (90度)
// 计算:
// x = sin(π/4)*0 = 0
// y = sin(π/4)*1 ≈ 0.707
// z = sin(π/4)*0 = 0
// w = cos(π/4) ≈ 0.707
new THREE.Quaternion(0, 0.7071067811865475, 0, 0.7071067811865476)
        可视化理解
可以把四元数想象为:
- 
(x, y, z) 指向旋转轴的方向
 - 
w 的大小决定了旋转的角度
 - 
四元数的长度(模)总是1(单位四元数)
 
在Three.js中的实际应用
            
            
              javascript
              
              
            
          
          // 创建一个绕(1,1,0)轴旋转45度的四元数
const axis = new THREE.Vector3(1, 1, 0).normalize();
const angle = Math.PI / 4; // 45度
const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle(axis, angle);
console.log(quaternion);
// 输出类似:Quaternion {x: 0.22, y: 0.22, z: 0, w: 0.92}
// 其中x,y,z是旋转轴分量(已规范化),w是角度分量
        重要特性
- 
单位长度 :
所有表示旋转的四元数都应该是单位四元数:
javascriptx² + y² + z² + w² = 1 
2.规范化 :
如果手动修改了四元数值,应该调用:
            
            
              javascript
              
              
            
          
          quaternion.normalize();
        3.逆四元数 :
表示相反旋转的四元数可以通过取共轭获得:
            
            
              javascript
              
              
            
          
          const inverse = quaternion.clone().conjugate();
        理解四元数的四个分量含义有助于在3D编程中更有效地使用它们,特别是在需要精确控制旋转或进行复杂旋转运算时。
二.欧拉角(Euler Angle)三个分量的含义
在Three.js中,欧拉角使用THREE.Euler类表示,由三个分量(x, y, z)组成,分别表示绕三个轴的旋转角度。
三个分量的具体含义
- 
x分量:
- 
表示绕X轴的旋转角度(俯仰角/Pitch)
 - 
正值:物体向前倾斜(低头)
 - 
负值:物体向后倾斜(抬头)
 
 - 
 - 
y分量:
- 
表示绕Y轴的旋转角度(偏航角/Yaw)
 - 
正值:物体向右转
 - 
负值:物体向左转
 
 - 
 - 
z分量:
- 
表示绕Z轴的旋转角度(滚转角/Roll)
 - 
正值:物体顺时针旋转
 - 
负值:物体逆时针旋转
 
 - 
 
旋转顺序的重要性
欧拉角的旋转顺序非常重要,Three.js默认使用"XYZ"顺序:
            
            
              javascript
              
              
            
          
          const euler = new THREE.Euler(x, y, z, 'XYZ');
        其他可能的顺序包括:'YXZ'、'ZXY'、'ZYX'、'YZX'、'XZY'等。不同顺序会导致完全不同的最终旋转结果。
实际示例
            
            
              javascript
              
              
            
          
          // 创建一个绕X轴旋转45度,Y轴旋转30度的欧拉角
const euler = new THREE.Euler(
  Math.PI/4,    // X轴旋转45度 (π/4弧度)
  0.523598776,  // Y轴旋转30度 (约0.52弧度)
  0,            // Z轴不旋转
  'XYZ'         // 旋转顺序
);
// 应用到物体
mesh.rotation.copy(euler);
        万向节锁问题
当绕第二个轴旋转±90度时,会出现万向节锁现象,导致失去一个旋转自由度。例如:
- 在"XYZ"顺序下,当Y轴旋转90度时,X和Z轴的旋转会变得相同
 
与四元数的对比
| 特性 | 欧拉角 | 四元数 | 
|---|---|---|
| 表示方式 | 三个角度值 | 四个数值(x,y,z,w) | 
| 直观性 | 高 | 低 | 
| 万向节锁 | 存在 | 不存在 | 
| 插值 | 线性插值不自然 | 球面插值(Slerp)平滑 | 
| 组合旋转 | 顺序敏感,计算复杂 | 简单四元数乘法 | 
使用建议
- 
适合使用欧拉角的场景:
- 
简单的单轴旋转
 - 
需要直观角度控制的编辑器工具
 - 
不需要复杂旋转组合的情况
 
 - 
 - 
应避免使用欧拉角的情况:
- 
需要绕任意轴旋转
 - 
需要平滑的旋转动画
 - 
需要避免万向节锁的复杂旋转
 
 - 
 
理解欧拉角三个分量的含义对于正确控制3D物体的旋转至关重要,特别是在需要精确控制物体朝向的应用中。
三.四元数(Quaternion)与欧拉角(Euler)的区别
四元数和欧拉角都是表示3D旋转的方式,但它们在实现和特性上有显著差异。以下是两者的主要区别:
1. 数学表示
欧拉角:
- 
使用三个角度值表示旋转(通常为x, y, z)
 - 
例如:
new THREE.Euler(0.5, 0.2, 0.1)表示绕x轴旋转0.5弧度,y轴0.2弧度,z轴0.1弧度 
四元数:
- 
使用四个数值(x, y, z, w)表示旋转
 - 
例如:
new THREE.Quaternion(x, y, z, w) 
2. 万向节锁(Gimbal Lock)问题
欧拉角:
- 
存在万向节锁问题,当某个轴的旋转达到90度时,会失去一个自由度
 - 
导致旋转行为不符合预期
 
四元数:
- 
不存在万向节锁问题
 - 
可以表示任意旋转而不丢失自由度
 
3. 插值效果
欧拉角:
- 
线性插值可能导致旋转路径不自然
 - 
旋转动画可能出现抖动或突变
 
四元数:
- 
可以使用球面线性插值(Slerp)
 - 
旋转动画平滑自然
 
4. 计算复杂度
欧拉角:
- 
计算简单,直观易懂
 - 
适合简单的旋转操作
 
四元数:
- 
计算相对复杂
 - 
但组合旋转(四元数乘法)效率更高
 
5. 使用场景对比
| 特性 | 欧拉角 | 四元数 | 
|---|---|---|
| 直观性 | 高(直接对应轴旋转角度) | 低(数学抽象) | 
| 万向节锁 | 有 | 无 | 
| 插值效果 | 差 | 优 | 
| 组合旋转 | 顺序依赖,计算复杂 | 简单乘法运算 | 
| 存储空间 | 3个值 | 4个值 | 
| 规范化 | 不需要 | 需要保持单位长度 | 
实际应用建议
1.使用欧拉角当:
- 
需要直观的角度控制(如编辑器中的旋转工具)
 - 
进行简单的单轴旋转
 - 
不需要复杂旋转组合或插值
javascript// 欧拉角简单旋转示例 mesh.rotation.x = Math.PI/4; // 绕X轴旋转45度 
2.使用四元数当:
理解这两种旋转表示方式的差异,可以帮助你在Three.js开发中选择最适合特定场景的旋转方法
- 
需要避免万向节锁
 - 
进行复杂的旋转组合
 - 
需要平滑的旋转动画
 - 
绕任意轴旋转
javascript// 四元数旋转示例 const axis = new THREE.Vector3(1, 1, 0).normalize(); const angle = Math.PI/3; // 60度 mesh.quaternion.setFromAxisAngle(axis, angle);转换关系
两者可以相互转换:
 
            
            
              javascript
              
              
            
          
          // 欧拉角转四元数
const euler = new THREE.Euler(0.5, 0.2, 0.1);
const quat = new THREE.Quaternion().setFromEuler(euler);
// 四元数转欧拉角
const newEuler = new THREE.Euler().setFromQuaternion(quat);
        性能考虑
- 
频繁的欧拉角与四元数转换会影响性能
 - 
Three.js内部实际上使用四元数存储旋转,当修改
object.rotation(欧拉角)时,内部会自动转换为四元数 - 
对于频繁更新的旋转操作,直接操作四元数更高效