ThreeJS零基础入门-三种坐标系位置数据的转换
Posted Geeker工作坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreeJS零基础入门-三种坐标系位置数据的转换相关的知识,希望对你有一定的参考价值。
使用ThreeJS进行交互和动画是经常需要用到坐标转换,比如从屏幕坐标转换为世界坐标,或者进行反向转换。两者之间的相互转换主要是以下三种坐标系之间的转换:屏幕坐标、标准坐标、世界坐标系。
屏幕坐标系和标准坐标系
先来了解一下这两个坐标系的定义,具体如下图所示:
可以看到屏幕上坐标系的起点(0,0)在左上角,而标准坐标系的起点在canvas中心处。
屏幕坐标转换为3D世界坐标
假设3D画布的大小填满window
假如我们要通过鼠标来操控3D画布内的场景对象,需要将鼠标的坐标位置转换为3D世界坐标,具体流程为屏幕坐标->标准坐标->世界坐标
具体代码示例如下:
import {Vector3} from 'three';
onMouseClicked() {
const mouseX = event.clientX;//鼠标单击坐标X
const mouseY = event.clientY;//鼠标单击坐标Y
// 屏幕坐标转标准设备坐标
const x = ( mouseX / window.innerWidth ) * 2 - 1;
const y = -( mouseY / window.innerHeight ) * 2 + 1;
//标准设备坐标(z=0.5这个值并没有一个具体的说法)
const stdVector = new Vector3(x, y, 0.5);
// 通过unproject方法,可以将标准设备坐标转世界坐标
const worldVector = stdVector.unproject(camera);
// 进行剩下操作,比如判断鼠标是否选中某个物体
}
// 窗口鼠标单击
// window.addEventListener('click',onMouseClicked);
假设3D画布的只是window中的一个窗口,比如某个div内的canvas
这时候只要获取到canvas所在的div的宽高及左上位移数据就可以计算了,具体如下:
const mouseX = event.clientX;//鼠标单击坐标X
const mouseY = event.clientY;//鼠标单击坐标Y
const rect = someDiv.getBoundingClientRect();
const x = ((mouseX - rect.left) / someDiv.clientWidth) * 2 - 1;
const y = - ((mouseY - rect.top) / someDiv.clientHeight) * 2 + 1;
const stdVector = new Vector3(x, y, 0.5);
// 通过unproject方法,可以将标准设备坐标转世界坐标
const worldVector = stdVector.unproject(camera);
3D世界坐标转换为屏幕坐标
反过来,如果要求出物体响应的屏幕坐标,世界坐标->标准坐标->屏幕坐标,那么可以这样:
// const box = ...
const worldVector = new Vector3(
box.position.x,
box.position.y,
box.position.z
);
//世界坐标转标准设备坐标
const stdVector = worldVector.project(camera);
const a = window.innerWidth / 2;
const b = window.innerHeight / 2;
//标准设备坐标转屏幕坐标x,y
const x = Math.round(stdVector.x * a + a);
const y = Math.round(-stdVector.y * b + b);
这时候只要获取到canvas所在的div的宽高及左上位移数据就可以计算了,具体如下:
// const box = ...
const worldVector = new Vector3(
box.position.x,
box.position.y,
box.position.z
);
const rect = someDiv.getBoundingClientRect();
//世界坐标转标准设备坐标
const stdVector = worldVector.project(camera);
const a = rect.width / 2;
const b = rect.height / 2;
//标准设备坐标转屏幕坐标x,y
const x = Math.round(stdVector.x * a + a) + rect.left;
const y = Math.round(-stdVector.y * b + b) + rect.top;
以上是关于ThreeJS零基础入门-三种坐标系位置数据的转换的主要内容,如果未能解决你的问题,请参考以下文章
在具有不同坐标轴的系统之间转换欧拉角(Unity 和 Threejs)