threejs 模型 世界坐标系和设备坐标系

前言

开发中遇到需求需要点击屏幕位置处,生成一个类似圆形弹窗面板,这个交互需要进行的坐标转换为模型坐标(局部坐标)=>场景坐标(世界坐标)=>标准设备坐标=>屏幕空间坐标,也就是一个将3D坐标转换为2D坐标的过程,话不多说,上代码!

模型坐标转场景坐标

模型坐标是以模型为原点绘制xyz轴的坐标点,先将模型坐标点通过与模型的matrix相乘就能得到场景中的坐标

// 假设point是模型中的vector3坐标点
const point = new THREE.Vector3(10, 10, 10)
// point2为转换出的场景中的坐标,mesh为此模型的实体
const point2 = point.clone().applyMatrix4(mesh.matrix)

场景坐标转设备坐标

场景坐标是以vector3(0,0,0)为原点的坐标点,通过vector3的project(camera)投射的相机中,返回在camera相机对象矩阵变化下对应的标准设备坐标,标准设备坐标的xyz范围是[-1, 1]

// point3是设备坐标
const point3 = point2.clone().project(scene.camera)

设备坐标转屏幕坐标

这里先写转换公式,后面会展示推导过程

// point4就是转换的屏幕坐标
const halfWidth = scene.dom.offsetWidth / 2
const halfHeight = scene.dom.offsetHeight / 2
const point4 = new THREE.Vector3(0, 0, 0)
point4.x = Math.round(point3.x * halfWidth + halfWidth)
point4.y = Math.round(point3.y * halfHeight + halfHeight)

设备坐标转屏幕的公式推导

threejs是通过canvas画布绘制图形的,因为屏幕坐标系就是canvas中的坐标系,也就是左上角[0, 0]是坐标原点,在threejs中一个物体的坐标是三维坐标,原点默认在屏幕中心[0, 0, 0],且xyz的范围是[-1, 1],因此图片表示为

QQ截图20230407172943.png

通过Vector3对象的方法project,方法的参数是相机对象,语句worldVector.project(camera);返回的结果是世界坐标worldVector在camera相机对象矩阵变化下对应的标准设备坐标, 标准设备坐标xyz的范围是[-1,1]。

ThreeJS 中,画布一般是全屏的,因此画布的宽高 w,h 就是:window.innerWidth 和 window.innerHeight,所以 Three 的空间坐标系中点 (cx, cy)在屏幕坐标系中就是:(w / 2,h / 2)。

假设 canvas 中有一点 (x,y),这个点在空间坐标系中为 (x1,y1),那么这个转换公式是:


x1=(x/w)21

y1=(y/h)2+1

QQ截图20230407173131.png

3D和2D之间就可以通过固定公式进行转换

转换出来坐标的坑

这个时候转换出来的坐标x,y,是相对于canvas的,换到页面中,如果还有边距这些属性的话也应该加上那段距离这个点才是跟鼠标点击的点完美切合

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值