在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ Threejs【坐標(biāo)轉(zhuǎn)換】如何讓annotation跟隨物體一起旋轉(zhuǎn)

Threejs【坐標(biāo)轉(zhuǎn)換】如何讓annotation跟隨物體一起旋轉(zhuǎn)

現(xiàn)在根據(jù)鼠標(biāo)點(diǎn)擊的屏幕位置能夠得到屏幕的坐標(biāo)event.clientXevent.clientY,然后我的annotation就初始化在這個(gè)屏幕坐標(biāo)的位置,那么如何綁定annotation和三維物體,使得物體旋轉(zhuǎn)的時(shí)候可以讓annotation跟隨物體一起旋轉(zhuǎn)呢?
問題一:我知道的一種方法如下:

/* 修改注解屏幕位置函數(shù)體 實(shí)時(shí)更新,實(shí)際是三維坐標(biāo)向屏幕坐標(biāo)的映射*/
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跟隨物體一起旋轉(zhuǎn)
    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和物體一起旋轉(zhuǎn),但是annotation的位置確實(shí)預(yù)先設(shè)定的:

var vector = new THREE.Vector3(50, 0, 250); // 控制annotation的位置

對(duì)于上面這行代碼,Vector3是個(gè)什么坐標(biāo)系下的向量呢?當(dāng)我在修改Vector3中的三個(gè)坐標(biāo)的時(shí)候,發(fā)現(xiàn)它并不是控制annotation的位置的向量,比如我把鼠標(biāo)點(diǎn)擊位置的參數(shù)傳遞過來,然后觸發(fā)鼠標(biāo)點(diǎn)擊事件,然后發(fā)現(xiàn)鼠標(biāo)點(diǎn)擊的位置并不是annotation的位置。如何把它和鼠標(biāo)點(diǎn)擊的屏幕坐標(biāo)掛鉤呢?

問題二:如果不預(yù)先設(shè)定好這個(gè)Vector3 而是使用鼠標(biāo),而是直接傳遞event.clientXevent.clientY

function updateAnnosPosition(){
    var canvas = renderer.domElement;
    var vector = new THREE.Vector3(clientX,clientY,-1);
    vector.project(camera);
    //這個(gè)位置的寫法有問題

    annos.style.left = clientX + "px";
    annos.style.top = clientY + "px";

    annos.style.opacity = spriteBehindObject ? 0.25 : 1;
}

這樣是可以在鼠標(biāo)點(diǎn)擊位置觸發(fā)annotation的,但是annotation卻不跟隨物體旋轉(zhuǎn)。
網(wǎng)上查了一下,大概是要進(jìn)行屏幕坐標(biāo)與三維坐標(biāo)之間的轉(zhuǎn)換:

_mouse.x = ( event.clientX / _domElement.width ) * 2 - 1;
_mouse.y = - ( event.clientY / _domElement.height ) * 2 + 1;

但是還是不行,求教該如何處理。

回答
編輯回答
我以為

(1)Vector3是個(gè)什么坐標(biāo)系下的向量呢?

Vector3是 three.js 定義的三維空間坐標(biāo)系里的向量

(2)如何把它和鼠標(biāo)點(diǎn)擊的屏幕坐標(biāo)掛鉤呢?

這個(gè)問題本質(zhì)是問:如何將three.js 三維坐標(biāo)轉(zhuǎn)換成屏幕二維坐標(biāo)

其實(shí)updateScreenPosition()函數(shù)就是將三維坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)的過程,我們可以改一下這個(gè)函數(shù),使之更通用:

/**
* 將three.js三維坐標(biāo)轉(zhuǎn)換成屏幕上的二維坐標(biāo)
* @param THREE.Vector3 vector three.js三維坐標(biāo)
* @return {x:int,y:int} 屏幕坐標(biāo)
*/
function transToScreenCoord(vector) {
    var screenCoord = {};
    vector.project(camera); //1
    screenCoord.x = Math.round((0.5 + vector.x / 2) * (canvas.width / window.devicePixelRatio));  //2
    screenCoord.y = Math.round((0.5 - vector.y / 2) * (canvas.height / window.devicePixelRatio));
    return screenCoord;
}

有了這個(gè)函數(shù),就可以把任意three.js三維坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo)。也就是實(shí)現(xiàn)了3維坐標(biāo)和屏幕坐標(biāo)掛鉤

接下來解釋一下這個(gè)轉(zhuǎn)換的過程:
vector.project(camera) 這句的意思是,將一個(gè)三維坐標(biāo),投影到相機(jī)平面上,使之變成一個(gè)二維坐標(biāo)。需要注意的是,投影得到的結(jié)果是一個(gè)標(biāo)準(zhǔn)向量(或者叫單位向量),其值是限定在[-1,1]范圍內(nèi)的。并且,這個(gè)向量是定義在以屏幕中心為原點(diǎn)的坐標(biāo)系里的,這個(gè)坐標(biāo)系和屏幕坐標(biāo)系的關(guān)系,就像下圖一樣:

圖片描述

假如經(jīng)過投影之后的點(diǎn)就是上圖中的點(diǎn)A(0.3,0.5),屏幕坐標(biāo)系是sx-s0-sy,相機(jī)平面坐標(biāo)系是tx-t0-ty,坐標(biāo)系的各項(xiàng)參數(shù)已經(jīng)標(biāo)在圖上,試著求A點(diǎn)在屏幕坐標(biāo)系中的坐標(biāo)。你求一遍的話,就會(huì)理解上面這個(gè)函數(shù)的意思。

(3)如果不預(yù)先設(shè)定好這個(gè)Vector3 而是使用鼠標(biāo),而是直接傳遞event.clientXevent.clientY,該怎么處理?

處理方法就是將這個(gè)屏幕二維坐標(biāo)轉(zhuǎn)three.js三維坐標(biāo),按照下面這個(gè)方法來處理:

var vector = new THREE.Vector3();
vector.x = ( event.clientX / _domElement.width ) * 2 - 1;
vector.y = - ( event.clientY / _domElement.height ) * 2 + 1;

把上面這段替換掉updateScreenPosition()函數(shù)中的:

 var vector = new THREE.Vector3(50, 0, 250); // 控制annotation的位置

應(yīng)該就可以了

2017年7月18日 16:41