Three模型设置旋转值的类型、相互转换(方向向量转欧拉角...)

 

Math.atan2(y, x) 是 JavaScript 提供的一种数学函数,用于计算点 (x, y) 相对于原点 (0, 0) 的极坐标角度(以弧度为单位)。

它特别适合处理在所有象限内的角度计算,避免了使用 Math.atan(y / x) 所需手动处理正负象限的问题。

注意,方向向量不可直接设置欧拉角的xyz:

例如THREE.Vector3(1,1,1)转位欧拉角后为THREE.Euler(-0.615, 0.785, 0, 'YXZ');

this._vector = new THREE.Vector3(1,1,1);

// 计算 yaw 和 pitch
const yaw = Math.atan2(this._vector.x, this._vector.z); // 绕 Y 轴旋转,水平角
const pitch = Math.asin(-this._vector.y); // 垂直方向旋转,俯仰角


// 设置欧拉角
this._euler.set(pitch, yaw, 0, 'XYZ'); // 使用 YXZ 顺序计算

three的模型旋转值能接受三种类型

1. 欧拉角 (THREE.Euler)

  • x: 绕 X 轴的旋转角度(弧度)。

  • y: 绕 Y 轴的旋转角度(弧度)。

  • z: 绕 Z 轴的旋转角度(弧度)。

  • order: 旋转顺序(默认 'XYZ')。

适用场景:1.常用于直接设置模型的 rotation 属性。2.支持角度动画和修改。

 

const euler = new THREE.Euler(Math.PI / 2, Math.PI / 4, 0, 'XYZ');
model.rotation.copy(euler);

2. 四元数 (THREE.Quaternion)表示旋转的另一种方式,避免了欧拉角的万向节死锁问题。

适用场景:1.用于更复杂和精确的旋转操作(如球形插值、连续旋转)。2.与物理引擎或方向计算结合使用。

const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2); // 绕 Y 轴旋转 90 度
model.quaternion.copy(quaternion);

3. 旋转矩阵 (THREE.Matrix4)表示包含旋转信息的 4x4 矩阵,可以同时表示平移、缩放和旋转。

适用场景:1.当旋转需要结合变换矩阵时使用。2.通常不直接应用到模型的 rotationquaternion 属性。

 

各种类型角之间的相互转换:

1. 欧拉角 → 四元数

使用 THREE.Quaternion.setFromEuler

const euler = new THREE.Euler(Math.PI / 2, Math.PI / 4, 0, 'XYZ'); // 欧拉角
const quaternion = new THREE.Quaternion();
quaternion.setFromEuler(euler);

console.log('Quaternion:', quaternion); // 四元数

2. 四元数 → 欧拉角

使用 THREE.Euler.setFromQuaternion

const quaternion = new THREE.Quaternion(0.5, 0.5, 0.5, 0.5); // 四元数
const euler = new THREE.Euler();
euler.setFromQuaternion(quaternion, 'XYZ');

console.log('Euler:', euler); // 欧拉角

3. 欧拉角 → 旋转矩阵

使用 THREE.Matrix4.makeRotationFromEuler

const euler = new THREE.Euler(Math.PI / 2, Math.PI / 4, 0, 'XYZ'); // 欧拉角
const matrix = new THREE.Matrix4();
matrix.makeRotationFromEuler(euler);

console.log('Rotation Matrix:', matrix); // 旋转矩阵

4. 旋转矩阵 → 欧拉角

使用 THREE.Euler.setFromRotationMatrix

const matrix = new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(Math.PI / 2, Math.PI / 4, 0, 'XYZ')); // 旋转矩阵
const euler = new THREE.Euler();
euler.setFromRotationMatrix(matrix, 'XYZ');

console.log('Euler:', euler); // 欧拉角

5. 四元数 → 旋转矩阵

使用 THREE.Matrix4.makeRotationFromQuaternion

const quaternion = new THREE.Quaternion(0.5, 0.5, 0.5, 0.5); // 四元数
const matrix = new THREE.Matrix4();
matrix.makeRotationFromQuaternion(quaternion);

console.log('Rotation Matrix:', matrix); // 旋转矩阵

6. 旋转矩阵 → 四元数

使用 THREE.Quaternion.setFromRotationMatrix

const matrix = new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(Math.PI / 2, Math.PI / 4, 0, 'XYZ')); // 旋转矩阵
const quaternion = new THREE.Quaternion();
quaternion.setFromRotationMatrix(matrix);

console.log('Quaternion:', quaternion); // 四元数

 

综合示例:三者互相转换

const euler = new THREE.Euler(Math.PI / 2, Math.PI / 4, 0, 'XYZ');
console.log('Initial Euler:', euler);

// 欧拉角 → 四元数
const quaternion = new THREE.Quaternion().setFromEuler(euler);
console.log('Quaternion:', quaternion);

// 四元数 → 旋转矩阵
const matrix = new THREE.Matrix4().makeRotationFromQuaternion(quaternion);
console.log('Rotation Matrix:', matrix);

// 旋转矩阵 → 欧拉角
const newEuler = new THREE.Euler().setFromRotationMatrix(matrix, 'XYZ');
console.log('New Euler:', newEuler);

注意事项

  1. 确保旋转顺序一致(例如 XYZYXZ 等),否则转换结果会不一致。

  2. 四元数在归一化状态下才是有效的,确保在设置之前调用 quaternion.normalize()

  3. 旋转矩阵是 4x4 的,因此也包含平移和缩放信息,但这里只使用旋转部分。

  4. 所有角度都以 弧度 为单位。

posted @ 2025-06-04 11:24  SimoonJia  阅读(84)  评论(0)    收藏  举报