Three.js中Object.rotation的旋转轴疑问:绕世界轴还是自身轴?
Three.js中rotation属性旋转的坐标系问题
你提到的这个问题其实是Three.js里欧拉角的工作逻辑和增量旋转方式的差异导致的,我给你掰扯明白:
核心结论
直接修改object.rotation的属性(比如object.rotation.x += Math.PI/4),本质是在调整描述物体姿态的欧拉角数值,Three.js会按默认的XYZ旋转顺序,从物体初始的局部坐标系(和世界坐标系重合的那个状态)重新计算整个旋转——这可不是“绕世界轴旋转”,只是欧拉角的特性让你产生了视觉错觉。要是想真的绕自身当前的局部轴转一段角度,得用Three.js专门提供的rotateX()/rotateY()/rotateZ()方法。
你的测试现象解析
我们一步步拆解你做的操作:
- 初始状态:物体的局部坐标系和世界坐标系完全重合,
rotation三个分量都是0。 - 第一次执行
object.rotation.x += Math.PI/4:欧拉角变成(π/4, 0, 0),按XYZ顺序,先绕局部X轴(此时和世界X轴重合)转45度,结果完全符合预期。 - 接着执行
object.rotation.y += Math.PI/4:欧拉角变成(π/4, π/4, 0),按XYZ顺序,先绕初始局部X转45度,再绕第一次旋转后的局部Y轴转45度——这时候物体的局部X轴已经和世界X轴不平行了。 - 再执行
object.rotation.z += Math.PI/4:欧拉角变成(π/4, π/4, π/4),按XYZ顺序完成三次旋转,物体的姿态是这三个欧拉角组合的结果。 - 最后再次执行
object.rotation.x += Math.PI/4:欧拉角变成(π/2, π/4, π/4),此时Three.js会重新按XYZ顺序计算整个旋转:先绕初始局部X轴(也就是世界X轴)转90度,再绕那次旋转后的局部Y轴转45度,最后绕再之后的局部Z轴转45度——这和你预想的“在当前姿态基础上绕局部X轴转45度”完全不是一回事,所以你会觉得像是绕世界X轴转了。
正确的局部增量旋转方式
如果你想在物体当前的姿态基础上,绕自身的局部轴旋转,别直接改rotation属性,用Three.js的实例方法:
// 绕自身当前局部X轴增量旋转45度 object.rotateX(Math.PI/4); // 绕自身当前局部Y轴增量旋转45度 object.rotateY(Math.PI/4); // 绕自身当前局部Z轴增量旋转45度 object.rotateZ(Math.PI/4);
这些方法是直接在物体当前的旋转矩阵上叠加旋转,真正实现了“绕当前局部轴转角度”的效果,不会出现欧拉角带来的那种奇怪视觉错觉。
补充:欧拉角的旋转顺序
Three.js里欧拉角的默认旋转顺序是XYZ,你也可以通过修改object.rotation.order来调整(比如改成'YXZ'、'ZXY'等),但不管哪种顺序,直接改rotation分量都是基于初始局部坐标系按顺序重新计算旋转,不是增量旋转。
内容的提问来源于stack exchange,提问作者Sarthak
相关产品推荐
相关产品推荐

