THREEJS 相机控制旋转

吉穆
• 阅读 2307

自行实现相机控制中的旋转功能.

相机控制旋转

对于相机旋转比较好的是使用球坐标系,相对于直角坐标系而言,球坐标系用来描述旋转更加合适直观且对于方位角、极角而言属于线性改变。对于线性函数我们是非常喜欢的,因为线性代表简单,能用越简单的函数来描述关系的就越适合。

再想一下如果使用笛卡尔坐标系来解决角度问题,那么一定是个三角函数,三角函数复杂度大于线性函数,这是我们不想看到的。

下图所示是球坐标系示意图:

THREEJS 相机控制旋转

代码解释

// 获取二维坐标 将原本在左上角的原点移动到屏幕中心,现在取值范围是[-1,1]
const offsetX = ((e.offsetX - mouseDownX) / dom.clientWidth) * 2;
const offsetY = ((e.offsetY - mouseDownY) / dom.clientHeight) * 2;
const matrix3 = new THREE.Matrix3();
mouseDownX = e.offsetX;
mouseDownY = e.offsetY;

// 记住原本相机的位置,我们只移动视角不移动位置
cameraPosition.copy(camera.position);

let rotation = new THREE.Vector3(0, 0, -1);
// 取得相机的世界坐标的归一化坐标
rotation.applyNormalMatrix(matrix3.setFromMatrix4(camera.matrixWorld));
let spherical = new THREE.Spherical();
// 从归一化坐标设置球,可以说是将相机坐标映射到了半径为1的球坐标系上
// setFromVector3用于设置theta和phi, 等于是将笛卡尔坐标系换算成球坐标系
spherical.setFromVector3(rotation);
// 上一步将笛卡尔坐标系换算成球坐标系后,theta和phi都是线性改变的了,对theta和phi相加减即可
spherical.theta -= offsetX;
spherical.phi += offsetY;

spherical.makeSafe();
rotation.setFromSpherical(spherical);

// 相机移动到原点 因为球坐标系在原点
camera.position.set(0, 0, 0);
camera.lookAt(rotation.x, rotation.y, rotation.z);
// 视角改变后移动到原位置,深藏功与名
camera.position.copy(cameraPosition);
camera.updateMatrixWorld();
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
凯特林 凯特林
4年前
移动端H5开发常用技巧总结
html篇常用的meta属性设置meta对于移动端的一些特殊属性,可根据需要自行设置<meta name"screenorientation" content"portrait" //Android 禁止屏幕旋转<meta name"fullscreen" content"yes"             //全屏显示
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Unity 围绕旋转角度限制(Transform.RotateAround)
    在Unity中可以利用Transform.RotateAround围绕指定物体进行旋转,但某些情况下可能需要对旋转角度进行控制。我是先计算出预设角度大小,然后判断是否小于或者超出旋转范围。如果小于则控制在最小范围内,如果大于则控制在最大范围内。相关代码如下://预设角度(当前角度加上将要增加/减少的角度
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Unity横屏
Android下发现Unity里面的Player设置,并不能完全有效,比如打开了自动旋转,启动的时候还是会横屏,修改XML添加以下代码<applicationandroid:icon"@drawable/ic\_launcher"                    android:label"@string/app\_name"
Wesley13 Wesley13
3年前
Unity脚本
1,Transform旋转 transform.Rotate(X,Y,Z);//分别绕X,Y,Z轴旋转,可写为绕某个轴旋转,栗子transform.Rotate(0,90,0); transform.Rotate(Vector3.right\Time.deltaTime);//以欧拉角旋转,顺序是ZXY,right是向X轴