March 31, 2025

Euler / Quaternion - 旋轉設定


Three.js 旋轉方式整理

🎯 旋轉的幾種方式

1️⃣ 直接修改 Euler 角

object.rotation.x = Math.PI / 4; // 旋轉 45 度

✅ 簡單直覺,但可能會遇到萬向鎖(Gimbal Lock)。


2️⃣ 使用 setFromEuler()

object.quaternion.setFromEuler(new THREE.Euler(Math.PI / 4, 0, 0));

✅ 轉換成 Quaternion,適合多軸旋轉,但仍可能有萬向鎖。


3️⃣ 使用 setFromAxisAngle()

const axis = new THREE.Vector3(0, 1, 0); // Y 軸
const angle = Math.PI / 4; // 旋轉 45 度
object.quaternion.setFromAxisAngle(axis, angle);

✅ 適合單一軸旋轉,避免萬向鎖。


4️⃣ 使用 multiplyQuaternions()

const q1 = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, Math.PI / 4, 0));
const q2 = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI / 4, 0, 0));
object.quaternion.multiplyQuaternions(q1, q2);

✅ 適合組合旋轉,無萬向鎖問題。


🔹 其他進階方式

5️⃣ 使用 lookAt()(朝向目標)

object.lookAt(new THREE.Vector3(0, 0, 0));

✅ 讓物體自動朝向目標。


6️⃣ 使用 applyQuaternion()(累加旋轉)

const q = new THREE.Quaternion();
q.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 4);
object.applyQuaternion(q);

✅ 適合剛體或物理引擎。


7️⃣ 使用 applyMatrix4()(直接修改矩陣)

const matrix = new THREE.Matrix4();
matrix.makeRotationY(Math.PI / 4);
object.applyMatrix4(matrix);

✅ 最高效能,適合同時處理縮放、旋轉、位移。


8️⃣ 使用 slerp()(平滑補間旋轉)

const targetRotation = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);
object.quaternion.slerp(targetRotation, 0.1); // 以 10% 速度補間

✅ 適合動畫或平滑轉場。


9️⃣ 使用 rotateX() / rotateY() / rotateZ()

object.rotateY(Math.PI / 4);

✅ 適合局部旋轉,但可能有萬向鎖。


🚀 旋轉方式比較

方式萬向鎖適合補間動畫適合單一軸適合多軸特色
.rotation.x/y/z❌ 有❌ 不適合✅ 適合❌ 不適合簡單直覺,但有萬向鎖
setFromEuler()❌ 有❌ 不適合✅ 適合❌ 不適合轉成 Quaternion,但仍有萬向鎖
setFromAxisAngle()✅ 無❌ 不適合✅ 最適合❌ 不適合適合固定軸旋轉
multiplyQuaternions()✅ 無✅ 最適合✅ 可以✅ 最適合適合複合旋轉
lookAt()✅ 無❌ 需要額外處理❌ 不適合✅ 最適合讓物體面向目標
applyQuaternion()✅ 無✅ 可補間✅ 適合✅ 適合適合物理引擎
applyMatrix4()✅ 無❌ 不適合✅ 適合✅ 適合最高性能,適合變換矩陣
slerp()✅ 無✅ 最適合✅ 適合✅ 適合平滑補間旋轉
rotateX/Y/Z()❌ 可能有❌ 不適合✅ 適合❌ 不適合以自身座標旋轉

🎯 最佳選擇

這樣你就能完全掌握 Three.js 的旋轉方式了! 🚀