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坐标系发生了旋转 ...
随机推荐
- Django ajax的简单使用、自定义分页器
一. ajax初识 1. 前后端传输数据编码格式contentType 使用form表单向后端提交数据时,必须将form表单的method由默认的get改为post,如果提交的数据中包含文件,还要将f ...
- hdu4587 Two Nodes 求图中删除两个结点剩余的连通分量的数量
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587 题目给了12000ms,对于tarjan这种O(|V|+|E|)复杂度的算法来说,暴力是能狗住的 ...
- java触发full gc的几种情况概述
前言 近期被问及这个问题,在此记录整理一下. System.gc()方法的调用 此方法的调用是建议JVM进行Full GC,虽然只是建议而非一定,但很多情况下它会触发 Full GC,从而增加Full ...
- Python模块---Wordcloud生成词云图
wordcloud是Python扩展库中一种将词语用图片表达出来的一种形式,通过词云生成的图片,我们可以更加直观的看出某篇文章的故事梗概. 首先贴出一张词云图(以哈利波特小说为例): 在生成词云图之前 ...
- JVM 调优工具
JMeter LoadRunner 压力测试工具 JConsole 是一个内置 Java 性能分析器,可以查看内存,线程,类,CPU 等的使用情况,可以通过线程去查看线程的试用情况,死锁可以被检 ...
- linux svn 批量添加
近期开始用svn来进行代码版本的维护管理,之前一直用git,两个感觉大同小异.用svn命令行来添加文件的话需要一个一个的选,很是蛋疼,于是就写了个shell脚本,批量添加文件,还在改进中... #!/ ...
- python项目依赖的生成与使用
1.cd到相关项目下并创建虚拟环境 ~$ pipenv install --dev 2.激活虚拟环境 ~$ pipenv shell 3.执行命令 ~$ pip freeze > require ...
- gold 30min
- 140行Python代码实现Flippy Bird
140行代码实现Flippy Bird 话说这游戏中文名叫什么来着,死活想不起来了,算了话不多说,140行实现小游戏系列第二章,依然是简单小游戏,与数独游戏相比,在游戏界面显示上更难一些,但是在逻辑方 ...
- elasticesearch搜索返回高亮关键字
pre_tags 前缀标签 post_tags 后缀标签 tags_schema 设置为styled可以使用内置高亮样式 require_field_match 多字段高亮需要设置为false 使用h ...