zoukankan      html  css  js  c++  java
  • 【Three.js】OrbitControl 旋转

    一、摘要

         分析了OrbitControl的基本原理。

    二、资源

         源码地址:

    三、分析

           最外层框架:OrbitControl 为函数对象,原型处理

    THREE.OrbitControls = function ( object , domElement){
        ...
    }
    
    THREE.OrbitControls.protorype = Object.create ( THREE.EventDispatcher.prototype);

          object : 控制的对象

          domElement : 3D模型控制范围 , 缺省为document 。 

          接下去开始是一些变量定义以及函数定义,看旋转实现即

    this.domElement.addEventListener( 'mousedown', onMouseDown, false );

          onMouseDown函数处理:捕捉event.button时间(0|1|2)分别对(left|middle|right),对应事件(rotate|zoom|pan)

    if ( event.button === 0 ) {
                if ( scope.noRotate === true ) return;
    
                state = STATE.ROTATE;
    
                rotateStart.set( event.clientX, event.clientY );
    
            } 
    else{
    .....
    }
    
    scope.domElement.addEventListener( 'mousemove', onMouseMove, false );
    scope.domElement.addEventListener( 'mouseup', onMouseUp, false );
    scope.dispatchEvent( startEvent );

       变量说明:

        scope = this;

        rotateStart , rotateEnd 为Vector2。记录当前二维坐标为初始终止点。

        增加监听mousemove,mouseup。

        mousemove事件onMouseMove:

    if ( state === STATE.ROTATE ) {
    
                if ( scope.noRotate === true ) return;
    
                rotateEnd.set( event.clientX, event.clientY );
                rotateDelta.subVectors( rotateEnd, rotateStart );
    
                // rotating across whole screen goes 360 degrees around
                scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
    
                // rotating up and down along whole screen attempts to go 360, but limited to 180
                scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
    
                rotateStart.copy( rotateEnd );
    
            } 
    else{
        ...
    }
    scope.update();

           鼠标移动中,记录当前坐标为rotateEnd,计算start与End差为rotateDelta。rotateLeft与rotateUp将二维差值记录到 角度差值 thetaDelta  与 phiDelta中。

           代码中可以看到thetaDelta 与x方向偏移的,phidelta与y偏移成正比。直观得想,x方向移动即让物体沿经度大圆的旋转,过中心绕Y轴。y方向即物体的上下旋转。

           接下来就是theta 和 phi 的问题。高中立体几何基本知识了。theta和phi就是下面2个角度了。

       

                重点在于scope.update.

        update做的主要事情也就几件

        重新计算theta和phi,计算移动后的三维坐标。控制旋转。之后可加上自己对旋转角度的控制。

    theta += thetaDelta;
    phi += phiDelta;

      加上pan改变target的位置,调整位置。

    // move target to panned location
     this.target.add( pan );
    
     offset.x = radius * Math.sin( phi ) * Math.sin( theta );
     offset.y = radius * Math.cos( phi );
     offset.z = radius * Math.sin( phi ) * Math.cos( theta );
    
     position.copy( this.target ).add( offset );
    
     this.object.lookAt( this.target );

    四、总结

         OrbitControl处理比较好理解,ThrackballControl.js的方式好像是放在一个半斤为1的球上来控制。

                

        

      

           

  • 相关阅读:
    javascript:;禁用a标签默认功能的缺点。
    chrome中image图片预留位置的问题
    line-height和vertical-algin
    关于font-size对垂直居中影响的问题
    网络OSI七层模型及各层作用 与 TCP/IP
    NB-IoT,LoRA,WIFI,蓝牙,Zigbee,MQTT,CoAP之间的关系
    常见的十大物联网通讯技术优劣及应用场景
    物联网的七大通信协议
    设备树DTS 学习:学习总结
    设备树DTS 学习:Linux DTS文件加载过程
  • 原文地址:https://www.cnblogs.com/hundan/p/3614542.html
Copyright © 2011-2022 走看看