OrbitControl 旋转

原文地址:
http://www.cnblogs.com/hundan/p/3614542.html?utm_source=tuicool&utm_medium=referral#undefined

一、摘要

分析了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 aroundscope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );// rotating up and down along whole screen attempts to go 360, but limited to 180scope.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 locationthis.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的球上来控制。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部