如何绕 X、Y 和 Z 轴旋转 Object3d 而不会翻转轴或导致万向节锁定?
How to rotate Object3d around X,Y & Z axis without having the axes to flip or cause gimbal lock?
可能是 threejs 的旋转问题没有 9000,我只是想有 3 个 UI 按钮,每次单击每个按钮时,在 x、y 和 z 方向上将对象增量旋转 90 度,这有多难?
使用使用欧拉的常规旋转方法将导致万向节锁定,使用四元数轴将随机翻转,其中 z 轴将在某一点或另一点成为 y 轴。
请看一下我的工作演示:http://grutex.com/webgl/demos/help/
编辑:这里是旋转函数部分:
function z_rotate(){
var startAngle = 0;
var start = {angle: startAngle};
var end = {angle: startAngle + 90};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
my_object.rotateOnAxis(new THREE.Vector3(0,0,1),degreeToRadians(startAngle-lastAngle));
lastAngle=startAngle;
})
.start();
}
function x_rotate(){
var startAngle = 0;
var start = {angle: startAngle};
var end = {angle: startAngle + 90};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
my_object.rotateOnAxis(new THREE.Vector3(1,0,0),degreeToRadians(startAngle-lastAngle));
lastAngle=startAngle;
})
.start();
}
function y_rotate(){
var startAngle = 0;
var start = {angle: startAngle};
var end = {angle: startAngle + 90};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
my_object.rotateOnAxis(new THREE.Vector3(0,1,0),degreeToRadians(startAngle-lastAngle));
lastAngle=startAngle;
})
.start();
}
正如@WestLangley 指出的那样,我应该将 3d 对象附加和分离到父枢轴点 (THREE.Object3D),在补间开始之前将 3d 对象附加到枢轴点并在补间完成后分离枢轴点并将其旋转重置为 (0,0,0)
@WestLangley 回答:Three.js: Adding and Removing Children of Rotated Objects
新修改的旋转函数:
var axis_x = new THREE.Vector3( 1, 0, 0 ).normalize();
function x_rotate(){
pivot_attach();
var startAngle = 0;
var start = {angle: degreeToRadians(startAngle)};
var end = {angle: degreeToRadians(startAngle + 90)};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
pivot.rotateOnAxis(axis_x,startAngle-lastAngle);
lastAngle=startAngle;
})
.start().onComplete(pivot_detach);
}
function pivot_attach() {
pivot.updateMatrixWorld();
THREE.SceneUtils.attach( my_object, scene, pivot );
}
function pivot_detach() {
pivot.updateMatrixWorld();
my_object.updateMatrixWorld(); // if not done by the renderer
THREE.SceneUtils.detach( my_object, pivot, scene );
pivot.rotation.set( 0, 0, 0 );
}
别忘了将枢轴添加到场景中 "scene.add(pivot);"
可能是 threejs 的旋转问题没有 9000,我只是想有 3 个 UI 按钮,每次单击每个按钮时,在 x、y 和 z 方向上将对象增量旋转 90 度,这有多难?
使用使用欧拉的常规旋转方法将导致万向节锁定,使用四元数轴将随机翻转,其中 z 轴将在某一点或另一点成为 y 轴。
请看一下我的工作演示:http://grutex.com/webgl/demos/help/
编辑:这里是旋转函数部分:
function z_rotate(){
var startAngle = 0;
var start = {angle: startAngle};
var end = {angle: startAngle + 90};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
my_object.rotateOnAxis(new THREE.Vector3(0,0,1),degreeToRadians(startAngle-lastAngle));
lastAngle=startAngle;
})
.start();
}
function x_rotate(){
var startAngle = 0;
var start = {angle: startAngle};
var end = {angle: startAngle + 90};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
my_object.rotateOnAxis(new THREE.Vector3(1,0,0),degreeToRadians(startAngle-lastAngle));
lastAngle=startAngle;
})
.start();
}
function y_rotate(){
var startAngle = 0;
var start = {angle: startAngle};
var end = {angle: startAngle + 90};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
my_object.rotateOnAxis(new THREE.Vector3(0,1,0),degreeToRadians(startAngle-lastAngle));
lastAngle=startAngle;
})
.start();
}
正如@WestLangley 指出的那样,我应该将 3d 对象附加和分离到父枢轴点 (THREE.Object3D),在补间开始之前将 3d 对象附加到枢轴点并在补间完成后分离枢轴点并将其旋转重置为 (0,0,0)
@WestLangley 回答:Three.js: Adding and Removing Children of Rotated Objects
新修改的旋转函数:
var axis_x = new THREE.Vector3( 1, 0, 0 ).normalize();
function x_rotate(){
pivot_attach();
var startAngle = 0;
var start = {angle: degreeToRadians(startAngle)};
var end = {angle: degreeToRadians(startAngle + 90)};
var lastAngle=0;
var tween = new TWEEN.Tween(start)
.to(end, 400)
.easing( TWEEN.Easing.Quadratic.Out )
.onUpdate(function(){
startAngle=this.angle;
pivot.rotateOnAxis(axis_x,startAngle-lastAngle);
lastAngle=startAngle;
})
.start().onComplete(pivot_detach);
}
function pivot_attach() {
pivot.updateMatrixWorld();
THREE.SceneUtils.attach( my_object, scene, pivot );
}
function pivot_detach() {
pivot.updateMatrixWorld();
my_object.updateMatrixWorld(); // if not done by the renderer
THREE.SceneUtils.detach( my_object, pivot, scene );
pivot.rotation.set( 0, 0, 0 );
}
别忘了将枢轴添加到场景中 "scene.add(pivot);"