Three.js 如何实现绕指定轴按绝对角度旋转3D对象
你用obj.rotation.y = 0不生效的核心原因是,rotateAboutPoint函数实现绕点旋转的逻辑是同时修改物体的位置position和自身旋转属性,你只重置了旋转属性,之前旋转带来的位置偏移还存在,自然无法回到初始状态。
以下是两种可行的解决方案:
方案1:记录初始状态,每次应用绝对角度前重置
这是改造成本最低的方案,不需要修改原旋转函数:
- 物体达到你认为「旋转角度为0」的状态后,提前保存它的初始位置和旋转状态:
// 只需要在初始化阶段执行一次即可 const initPosition = obj.position.clone(); const initQuaternion = obj.quaternion.clone();
- 每次要设置绝对旋转角度时,先把物体重置回初始状态,再调用
rotateAboutPoint传入目标角度即可:
// 重置到0度对应状态 obj.position.copy(initPosition); obj.quaternion.copy(initQuaternion); // 传入目标绝对角度 rotateAboutPoint(obj, rotatePoint, rotateAxis, targetTheta, pointIsWorld);
方案2:改写原函数,直接支持绝对角度参数
你可以给原函数增加isAbsolute参数,内部自动处理重置逻辑,适合频繁调用的场景:
// 新增isAbsolute参数:是否为绝对角度,默认false(累加模式) // 注:函数内引用的initPosition、initQuaternion为方案1中提前保存的0度状态变量 function rotateAboutPoint(obj, point, axis, theta, pointIsWorld = false, isAbsolute = false){ // 绝对角度模式下先重置回0度状态 if(isAbsolute){ obj.position.copy(initPosition); obj.quaternion.copy(initQuaternion); } if(pointIsWorld){ obj.parent.localToWorld(obj.position); } obj.position.sub(point); obj.position.applyAxisAngle(axis, theta); obj.position.add(point); if(pointIsWorld){ obj.parent.worldToLocal(obj.position); } obj.rotateOnAxis(axis, theta); }
使用的时候直接传入目标角度,最后一个参数设为true即可:
// 示例:直接设置绕指定点旋转到90度(对应弧度为Math.PI/2) rotateAboutPoint(obj, point, axis, Math.PI/2, false, true);
注意:如果物体在初始化后、开始绕点旋转前有其他位置、旋转修改,需要在修改完成、达到0度对应状态后,再执行初始状态的保存操作。
内容的提问来源于stack exchange,提问作者Ood
相关产品推荐
相关产品推荐

