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.通常不直接应用到模型的 rotation 或 quaternion 属性。
各种类型角之间的相互转换:
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);
注意事项
-
确保旋转顺序一致(例如
XYZ、YXZ等),否则转换结果会不一致。 -
四元数在归一化状态下才是有效的,确保在设置之前调用
quaternion.normalize()。 -
旋转矩阵是 4x4 的,因此也包含平移和缩放信息,但这里只使用旋转部分。
-
所有角度都以 弧度 为单位。

浙公网安备 33010602011771号