手写一个简单的 OrbitControls 轨道控制器

手写一个简单的 OrbitControls 轨道控制器

相信使用过THREE.JS的同学,都知道 OrbitControls 这个的轨道控制器,他是绕着一个观察点,来进行什么什么的… 反正就是那么个意思。
所以很明显OrbitControls的运动轨迹是一个球体,他是绕着球体进行运动的。
所以也很明显,我们只有知道每一点,球体的坐标 (x, y, z) 就可以实现这个效果,然后再把这个坐标,赋值给 相机对象就可以实现了

2.那么我们应该怎么获取到球体的坐标呢

在这里插入图片描述
这是我画的可视化图解,我们可以发现,球上的一点 P(x, y, z) 与 它的角度的之间的关系。
最后得出

x = R * Math.sin(theat) * Math.cos(phi);
y = R * Math.cos(theat);
z = R * Math.sin(theat) * Math.sin(phi); 

所以这就是前面的理论部分,接下来我们就要完成具体的编码

class OrbitiControls {constructor(camera, domElement) {this.camera = camera;this.domElement = domElement;// 创建一个鼠标位置对象this.mouse = {x: 0,y: 0,down: false}// 绕着的目标this.target = new Vector3(0,0,0);// 计算轨道球体半径this.radius = this.camera.position.distanceTo(this.target);// 记录旋转的角度this.rotate = {theta: Math.atan2(this.camera.position.x, this.camera.position.z),phi: Math.acos(this.camera.position.y / this.radius)}this.domElement.addEventListener('mousedown', this.onMouseDown.bind(this));this.domElement.addEventListener('mouseup', this.onMouseUp.bind(this));this.domElement.addEventListener('mousemove', this.onMouseMove.bind(this));}onMouseDown() {// 当鼠标按下时this.mouse.down = true;}onMouseUp() {// 当鼠标抬起时this.mouse.down = false;}onMouseMove(event) {if (this.mouse.down) {let x = event.movementX;let y = event.movementY;if (x > 3) x = 3;if (x < -3) x = -3;if (y > 3) y = 3;if (y < -3) y = -3;this.rotate.theta -= x * 0.01;this.rotate.phi -= y * 0.01;// 限制phi的范围if (this.rotate.phi < 0.1) {this.rotate.phi = 0.1;}if (this.rotate.phi > Math.PI - 0.1) {this.rotate.phi = Math.PI - 0.1;}//  根据角度计算相机位置this.camera.position.x =this.radius * Math.sin(this.rotate.phi) * Math.cos(this.rotate.theta);this.camera.position.y = this.radius * Math.cos(this.rotate.phi);this.camera.position.z =this.radius * Math.sin(this.rotate.phi) * Math.sin(this.rotate.theta);this.camera.lookAt(this.target);console.log(this.camera);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/812276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【我的代码生成器】React的FrmUser类源码

FrmUser 类的源码中&#xff1a;FrmUser btnSaveClick 等命名方式都是参考VB.Net的写法。 import React, { forwardRef, useImperativeHandle, useState, useEffect, } from "react"; import { makeStyles, TextField, Grid, Paper, Button, ButtonGroup, } from &q…

Ubuntu安装或卸载mariadb-server软件包

sudo apt install mariadb-server 检查MariaDB服务器的服务状态 service mariadb status 仅需要卸载MariaDB&#xff0c;而不是删除所有MariaDB相关软件包 sudo apt-get remove mariadb-server 从系统中完全删除MariaDB数据库&#xff0c;请按照以下步骤操作 sudo apt-get…

(delphi11最新学习资料) Object Pascal 学习笔记---第9章第3节( 真实世界中的异常处理)

9.3 真实世界中的异常处理 ​ 异常是一种很好的错误报告和错误处理机制&#xff08;不是在单个代码片段中&#xff0c;而是作为大型架构的一部分&#xff09;。一般来说&#xff0c;异常不应替代检查一个局部错误条件&#xff08;尽管有些开发人员会这样使用异常&#xff09;。…

AWTK 开源串口屏 MODBUS Server 模型

名称&#xff1a;modbus_server 功能&#xff1a;通过 modbus 协议提供服务&#xff0c;供远程客户端&#xff08;主站&#xff09;访问。 1. 创建 通过 modbus_server 创建模型。 示例&#xff1a; <window v-model"modbus_server" name"home_page&quo…

学习 Rust 的第二天:Cargo包管理器的使用

今天&#xff0c;我们来探讨一下 Cargo&#xff0c;这个强大而方便的 Rust 构建系统和包管理器。 Cargo 是一个稳健而高效的 Rust 构建系统和包管理器&#xff0c;旨在帮助管理项目依赖关系&#xff0c;并确保在不同环境下进行一致的构建。 使用 cargo 创建新程序&#xff1a…

npm install 报错权限问题

npm i 报错权限问题 npm install 报错权限问题 npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: npm10.5.0, npm WARN EBADENGINE required: { node: ^18.17.0 || >20.5.0 }, npm WARN EBADENGINE current: { node: v18.15.0, npm: 9.5.0 } …

软考之零碎片段记录(十三)+复习巩固(八)

一、学习 1. 磁头读取数据块 读取 t 块的文件。 磁头从一个磁道移植相邻刺刀需m毫秒, 在磁盘上半连续存放&#xff0c;相邻数据块的平均移动时间为n 个刺&#xff0c;每块的旋转起达时间和传输时间时 h毫秒和y 毫秒。读文件需要多久。 (m * n h y) t 2. 原型模型 不适合大…

Unity面经(自整)——Unity基础知识

Unity基础知识 1. Image和RawImage的区别 Image比RawImage更耗性能。Image只能使用sprite属性的图片。而RawImage什么都可以使用 2. Unity3D中的碰撞器Collider和触发器Trigger的区别 碰撞器是触发器的载体&#xff0c;而触发器是碰撞器上的一个属性。 如果IsTrigger为fal…

MySQL常见面试题(2024年最新)

目录 前言1.char和varchar的区别2.数据库的三大范式3.你了解sql的执行顺序吗&#xff1f;4.索引是什么5.索引的优点和缺点6.索引的类型7.索引怎么设计(优化)8.怎么避免索引失效(也属于sql优化的一种)9.索引的数据类型10.索引为什么使用树结构11.二叉查找树、B树、B树12.为什么使…

身份证识别ocr、身份证实名认证接口文档

每一次验证背后&#xff0c;都是对用户数据安全的承诺&#xff0c;对平台信誉的坚守。翔云身份证实名认证API&#xff0c;通过身份证识别接口仅需一键上传身份证图片即可快速识别身份证信息&#xff0c;翔云实名认证接口实时联网查验证件信息的真伪。 ​PHP身份证实名认证接口…

代码随想录学习Day 27

贪心算法理论基础 贪心的本质&#xff1a;通过每一阶段的局部最优推出全局最优。 思路&#xff1a;找局部最优&#xff0c;看能不能推出全局最优&#xff0c;并尝试举反例。 步骤&#xff1a; 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最…

TDengine taosAdapter启用HTTPS

HTTPS &#xff08;Hypertext Transfer Protocol Secure &#xff09;&#xff0c;是以安全为目标的 HTTP 通道&#xff0c;在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL&#xff0c;HTTPS 的安全基础是 SSL&#xff0c;因此加…

JDK、JRE 及 JVM 是什么?

一、JDK 是什么&#xff1f;有哪些内容组成&#xff1f; JDK 是 Java 开发工具包&#xff0c;包含 JVM 虚拟机&#xff08;Java 程序运行的地方&#xff09;、核心类库&#xff08;Java已经写好的东西&#xff0c;我们可以直接用&#xff09;、开发工具&#xff08;javac、jav…

算法打卡day45|动态规划篇13| Leetcode 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

算法题 Leetcode 300.最长递增子序列 题目链接:300.最长递增子序列 大佬视频讲解&#xff1a;300.最长递增子序列视频讲解 个人思路 没什么思路,菜就多练! 解法 动态规划 “子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而…

Razzashi Raptor

拉扎什迅猛龙 Razzashi Raptor 95000金&#xff08;游戏币&#xff09;比老虎便宜多了&#xff0c;捡漏啊 为啥我开团都不出&#xff0c;很生气&#xff0c;去打架&#xff01;&#xff01;

python-pytorch实现lstm模型预测文本输出0.1.00

python-pytorch实现lstm模型预测文本输出0.1.00 数据参考效果分词到数组准备数数据查看频次获取vacab生成输入数据训练测试连续预测 有问题还需要完善 数据 一篇新闻&#xff1a;https://news.sina.com.cn/c/2024-04-12/doc-inarqiev0222543.shtml 参考 https://blog.csdn.…

ArcGIS Desktop使用入门(三)图层右键工具——标注要素、将标注转换为注记

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…

零基础突破:开启你的IT行业之旅

零基础突破&#xff1a;开启你的IT行业之旅 在信息技术不断演进的今天&#xff0c;IT行业已成为众多职场人士和新手梦寐以求的领域。但对于那些没有任何相关背景知识的人来说&#xff0c;进入这一行业似乎是一条充满挑战的道路。然而&#xff0c;通过采取正确的方法和技巧&…

【Godot4自学手册】第三十六节圆形移动或扇形移动的铁球

在第三十四节我实现了来回无限滚动的伤害铁刺球&#xff0c;这一节我准备实现一个圆形移动或扇形移动&#xff0c;并带有链条的铁球。效果如下&#xff1a; 一、实现原理 绕一点做圆周运动&#xff0c;简单的说就是&#xff1a; 每一帧根据旋转的角度计算出下一个位置的坐标…

Redis--16--Spring Data Redis

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Spring Data Redishttps://spring.io/projects/spring-data-redis 1.依赖2.RedisTemplate3.案例 序列化1.默认是 JdkSerializationRedisSerializer2.添加Redis配置文…