Threejs【坐标转换】如何让annotation跟随物体一起旋转
现在根据鼠标点击的屏幕位置能够得到屏幕的坐标event.clientX
和event.clientY
,然后我的annotation就初始化在这个屏幕坐标的位置,那么如何绑定annotation和三维物体,使得物体旋转的时候可以让annotation跟随物体一起旋转呢?
问题一:我知道的一种方法如下:
/* 修改注解屏幕位置函数体 实时更新,实际是三维坐标向屏幕坐标的映射*/
function updateScreenPosition() {
var canvas = renderer.domElement; var vector = new THREE.Vector3(50, 0, 250); // 控制annotation的位置
vector.project(camera);
vector.x = Math.round((0.5 + vector.x / 2) * (canvas.width / window.devicePixelRatio)); // 控制annotation跟随物体一起旋转
vector.y = Math.round((0.5 - vector.y / 2) * (canvas.height / window.devicePixelRatio)); annotation.style.top = vector.y + "px";
annotation.style.left = vector.x + "px";
annotation.style.opacity = spriteBehindObject ? 0.25 : 1;
}
上面的方法可以控制annotation和物体一起旋转,但是annotation的位置确实预先设定的:
var vector = new THREE.Vector3(50, 0, 250); // 控制annotation的位置
对于上面这行代码,Vector3
是个什么坐标系下的向量呢?当我在修改Vector3
中的三个坐标的时候,发现它并不是控制annotation
的位置的向量,比如我把鼠标点击位置的参数传递过来,然后触发鼠标点击事件,然后发现鼠标点击的位置并不是annotation
的位置。如何把它和鼠标点击的屏幕坐标挂钩呢?
问题二:如果不预先设定好这个Vector3
而是使用鼠标,而是直接传递event.clientX
和event.clientY
function updateAnnosPosition(){
var canvas = renderer.domElement;
var vector = new THREE.Vector3(clientX,clientY,-1);
vector.project(camera);
//这个位置的写法有问题 annos.style.left = clientX + "px";
annos.style.top = clientY + "px"; annos.style.opacity = spriteBehindObject ? 0.25 : 1;
}
这样是可以在鼠标点击位置触发annotation的,但是annotation却不跟随物体旋转。
网上查了一下,大概是要进行屏幕坐标与三维坐标之间的转换:
_mouse.x = ( event.clientX / _domElement.width ) * 2 - 1;
_mouse.y = - ( event.clientY / _domElement.height ) * 2 + 1;
但是还是不行,求教该如何处理。
(1)Vector3是个什么坐标系下的向量呢?
Vector3是 three.js 定义的三维空间坐标系里的向量
(2)如何把它和鼠标点击的屏幕坐标挂钩呢?
这个问题本质是问:如何将three.js 三维坐标转换成屏幕二维坐标
其实updateScreenPosition()
函数就是将三维坐标转换成屏幕坐标的过程,我们可以改一下这个函数,使之更通用:
/**
* 将three.js三维坐标转换成屏幕上的二维坐标
* @param THREE.Vector3 vector three.js三维坐标
* @return {x:int,y:int} 屏幕坐标
*/
function transToScreenCoord(vector) {
var screenCoord = {};
vector.project(camera); //
screenCoord.x = Math.round((0.5 + vector.x / 2) * (canvas.width / window.devicePixelRatio)); //
screenCoord.y = Math.round((0.5 - vector.y / 2) * (canvas.height / window.devicePixelRatio));
return screenCoord;
}
有了这个函数,就可以把任意three.js三维坐标转换成屏幕坐标。也就是实现了3维坐标和屏幕坐标挂钩
接下来解释一下这个转换的过程:vector.project(camera)
这句的意思是,将一个三维坐标,投影到相机平面上,使之变成一个二维坐标。需要注意的是,投影得到的结果是一个标准向量(或者叫单位向量),其值是限定在[-1,1]范围内的。并且,这个向量是定义在以屏幕中心为原点的坐标系里的,这个坐标系和屏幕坐标系的关系,就像下图一样:
假如经过投影之后的点就是上图中的点A(0.3,0.5),屏幕坐标系是sx-s0-sy,相机平面坐标系是tx-t0-ty,坐标系的各项参数已经标在图上,试着求A点在屏幕坐标系中的坐标。你求一遍的话,就会理解上面这个函数的意思。
(3)如果不预先设定好这个Vector3
而是使用鼠标,而是直接传递event.clientX
和event.clientY
,该怎么处理?
处理方法就是将这个屏幕二维坐标转three.js三维坐标,按照下面这个方法来处理:
var vector = new THREE.Vector3();
vector.x = ( event.clientX / _domElement.width ) * 2 - 1;
vector.y = - ( event.clientY / _domElement.height ) * 2 + 1;
把上面这段替换掉updateScreenPosition()
函数中的:
var vector = new THREE.Vector3(50, 0, 250); // 控制annotation的位置
应该就可以了
Threejs【坐标转换】如何让annotation跟随物体一起旋转的更多相关文章
- Three.js之绘制中文文字并跟随物体
本周更新的需求是物体上显示文字信息,效果图如下: 加载字体 import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'; ...
- three.js 元素跟随物体效果
需求: 1.实现元素跟随指定物体位置进行位置变化 实现方案: 1--- Sprite 精灵 2 --- cavans 画图后创建模型贴图 3 --- CSS2DRenderer渲染方式 4 --- ...
- Unity3D——相机跟随物体移动
public Transform target; public float moveSmooth=5f; Vector3 offset; void Start () { offset = transf ...
- unity3d简单的相机跟随及视野旋转缩放
1.实现相机跟随主角运动 一种简单的方法是把Camera直接拖到Player下面作为Player的子物体,另一种方法是取得Camera与Player的偏移向量,并据此设置Camera位置,便能实现简单 ...
- SCRDet——对小物体和旋转物体更具鲁棒性的模型
引言 明确提出了三个航拍图像领域内面对的挑战: 小物体:航拍图像经常包含很多复杂场景下的小物体. 密集:如交通工具和轮船类,在航拍图像中会很密集.这个DOTA数据集的发明者也提到在交通工具和轮船类的检 ...
- 在threejs中对3D物体旋转的思考
今天在写threejs时,突然想到一个问题:一个3D物体需要旋转时,一般情况下简单的旋转我都是使用欧拉角,稍微复杂一些的情况我会把欧拉角转换成四元数进行旋转(欧拉角复杂旋转可能会产生的死锁问题),但是 ...
- Unity3d学习 相机的跟随
最近在写关于相机跟随的逻辑,其实最早接触相机跟随是在Unity官网的一个叫Roll-a-ball tutorial上,其中简单的涉及了关于相机如何跟随物体的移动而移动,如下代码: using Unit ...
- 首个threejs项目-前端填坑指南
第一次使用threejs到实际项目中,开始的时候心情有点小激动,毕竟是第一次嘛,然而做着做着就感受到这玩意水好深,满满的都是坑,填都填不过来.经过老板20天惨无人道的摧残,终于小有成就. 因为第一次搞 ...
- canvas 图片拖拽旋转之一——坐标转换translate
引言 对canvas中绘制的图片进行旋转操作,需要使用ctx.translate变换坐标系,将图片旋转的基点设为坐标系的原点,然后ctx.rotate旋转. 这个时候,因为canvas坐标系发生了旋转 ...
随机推荐
- 五分钟学后端技术:如何学习Redis、memcache等常用缓存技术
原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 什么是缓存 计算机中的缓存 做后端开发的同学,想必对缓存都不会陌生了,平时我们可能会使用Redis,MemCache这类 ...
- 201771010103 陈亚茹 《面向对象程序设计(java)》第一周学习总结
本人学号<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com https://w ...
- Python 趣题
如何优雅判断list为空 list_temp = [] if list_temp: # 存在值即为真 else: # list_temp是空的 在Python中,False,0,'',[],{},() ...
- 什么是DevOps ?
DevOps字面理解 DevOps(Development和Operations组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与 ...
- 计算智能(CI)之粒子群优化算法(PSO)(一)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 计算智能(Computational Intelligence , ...
- 一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 反向传播算法(Backpropagation Algorithm, ...
- 使用Keras进行深度学习:(三)使用text-CNN处理自然语言(上)
欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 上一篇文章中一直围绕着CNN处理图像数据进行讲解,而CNN除了处理 ...
- Jmeter接口测试之参数传递(十三)
在接口自动化测试中,经常会遇到的一种场景就是参数的场景,比如在用户列表中获取所有的用户列表,然后获取到某一个用户的ID,查看该用户的详细信息.首先在这里理清思路,它的流程是,首先获取到数据,然后在Jm ...
- softmax及python实现
相对于自适应神经网络.感知器,softmax巧妙低使用简单的方法来实现多分类问题. 功能上,完成从N维向量到M维向量的映射 输出的结果范围是[0, 1],对于一个sample的结果所有输出总和等于1 ...
- SpringBoot环境搭建及第一个程序运行(详细!)
spring boot简介 spring boot框架抛弃了繁琐的xml配置过程,采用大量的默认配置简化我们的开发过程. 所以采用Spring boot可以非常容易和快速地创建基于Spring 框架的 ...