现在根据鼠标点击的屏幕位置能够得到屏幕的坐标event.clientXevent.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.clientXevent.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.clientXevent.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跟随物体一起旋转的更多相关文章

  1. Three.js之绘制中文文字并跟随物体

    本周更新的需求是物体上显示文字信息,效果图如下: 加载字体 import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'; ...

  2. three.js 元素跟随物体效果

    需求: 1.实现元素跟随指定物体位置进行位置变化 实现方案: 1--- Sprite 精灵 2  --- cavans 画图后创建模型贴图 3 --- CSS2DRenderer渲染方式 4 --- ...

  3. Unity3D——相机跟随物体移动

    public Transform target; public float moveSmooth=5f; Vector3 offset; void Start () { offset = transf ...

  4. unity3d简单的相机跟随及视野旋转缩放

    1.实现相机跟随主角运动 一种简单的方法是把Camera直接拖到Player下面作为Player的子物体,另一种方法是取得Camera与Player的偏移向量,并据此设置Camera位置,便能实现简单 ...

  5. SCRDet——对小物体和旋转物体更具鲁棒性的模型

    引言 明确提出了三个航拍图像领域内面对的挑战: 小物体:航拍图像经常包含很多复杂场景下的小物体. 密集:如交通工具和轮船类,在航拍图像中会很密集.这个DOTA数据集的发明者也提到在交通工具和轮船类的检 ...

  6. 在threejs中对3D物体旋转的思考

    今天在写threejs时,突然想到一个问题:一个3D物体需要旋转时,一般情况下简单的旋转我都是使用欧拉角,稍微复杂一些的情况我会把欧拉角转换成四元数进行旋转(欧拉角复杂旋转可能会产生的死锁问题),但是 ...

  7. Unity3d学习 相机的跟随

    最近在写关于相机跟随的逻辑,其实最早接触相机跟随是在Unity官网的一个叫Roll-a-ball tutorial上,其中简单的涉及了关于相机如何跟随物体的移动而移动,如下代码: using Unit ...

  8. 首个threejs项目-前端填坑指南

    第一次使用threejs到实际项目中,开始的时候心情有点小激动,毕竟是第一次嘛,然而做着做着就感受到这玩意水好深,满满的都是坑,填都填不过来.经过老板20天惨无人道的摧残,终于小有成就. 因为第一次搞 ...

  9. canvas 图片拖拽旋转之一——坐标转换translate

    引言 对canvas中绘制的图片进行旋转操作,需要使用ctx.translate变换坐标系,将图片旋转的基点设为坐标系的原点,然后ctx.rotate旋转. 这个时候,因为canvas坐标系发生了旋转 ...

随机推荐

  1. 直方图均衡算法(Histogram Equalized)

    Lab1: Histogram Equalization 1. 实验环境(C++) 操作系统版本 MacOS Catalina 10.15 OpenCV4.0 (imgcodecs | core | ...

  2. 【HDU5934】Bomb——有向图强连通分量+重建图

    题目大意 二维平面上有 n 个爆炸桶,i−thi-thi−th爆炸桶位置为 (xi,yi)(x_i, y_i)(xi​,yi​) 爆炸范围为 rir_iri​ ,且需要 cic_ici​ 的价格引爆, ...

  3. 动态规划/MinMax-Predict the Winner

    2018-04-22 19:19:47 问题描述: Given an array of scores that are non-negative integers. Player 1 picks on ...

  4. 关于利用python进行验证码识别的一些想法

    转载:@小五义http://www.cnblogs.com/xiaowuyi 用python加“验证码”为关键词在baidu里搜一下,可以找到很多关于验证码识别的文章.我大体看了一下,主要方法有几类: ...

  5. arcgis连接oracle发布服务,提示数据未注册到服务器,手动注册服务器失败

    arcgis连接oracle数据库发布服务时候,分析之后提示:数据未注册到服务器上. 手动注册之后提示:数据客户端没有正确配置.实际上数据库客户端已经安装完成也可以使用. 设置 PATH 环境变量(仅 ...

  6. Hadoop 同步集群时间ntp

    root 用户操作 1,rpm -qa|grep ntp 查看机器是否安装ntp 2,vi /etc/ntp.conf 修改: #restrict 192.168.1.0 mask 255.255.2 ...

  7. 上传到码云时遇到:Incorrect username or password ( access token )

    由于之前上传到 码云时候使用命令:git push -u origin master时出现如下bug Incorrect username or password ( access token ) 时 ...

  8. 【宇哥带你玩转MySQL】索引篇(一)索引揭秘,看他是如何让你的查询性能指数提升的

    场景复现,一个索引提高600倍查询速度? 首先准备一张books表 create table books( id int not null primary key auto_increment, na ...

  9. [noip模拟20170921]模版题

      今天考的是一套很基础的模版题,但是我这种蒟蒻竟然还是没有AK,不得不说,蒟蒻和大佬的差别不是一点点啊 1.暴走的猴子(walk.pas/c/cpp) [题目描述] 从前有一个森林,森林里生活着一群 ...

  10. Blazor入门笔记(6)-组件间通信

    1.环境 VS2019 16.5.1.NET Core SDK 3.1.200Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.简介 在使用B ...