【问题标题】:How to rotate Object3d around X,Y & Z axis without having the axes to flip or cause gimbal lock?如何围绕 X、Y 和 Z 轴旋转 Object3d 而不使轴翻转或导致万向节锁定?
【发布时间】:2017-05-22 01:34:28
【问题描述】:

可能是threejs的旋转问题没有9000,我只是想要有3个UI按钮,每次点击都可以在x,y和z方向上将对象增量旋转90度,这有多难?

使用 euler 的常规旋转方法会导致云台锁定,并且使用 quanternions 轴将随机翻转,其中 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();

    }

【问题讨论】:

  • 欢迎来到 SO。请将您的代码添加到您的帖子中。提示:避免每帧调用new。创建对象的一个​​实例并重复使用它。
  • 研究this answer,并补间临时父对象的旋转。
  • @WestLangley 谢谢!,如果不是你,我会连续几天把头撞在墙上,你是我唯一希望回答我的人在 SO 上阅读了大量关于three.js 的答案,我将在下面发布调整后的代码

标签: three.js rotation quaternions


【解决方案1】:

正如@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);”

【讨论】:

  • 以弧度指定开始的角度。
  • 因此它们是“degreeToRadians()”函数,或者我可以使用“THREE.Math.degToRad(degrees);”方法。
  • 您的角度以度为单位。 angle: startAngle + 90
  • 哦,对了,你的意思是在更新循环之外改变它,修复它应该节省一些处理周期,我应该睡一会儿哈哈
猜你喜欢
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 2015-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 2018-02-06
相关资源
最近更新 更多