[Threejs]三種座標系位置數據的轉換

webGL中主要有6種座標系.接下來看看如何在以下三種座標系之間進行座標數據的轉換:屏幕座標系,標準座標系,世界座標系.

  • 屏幕座標系和標準設備座標系

先來了解一下這兩個座標系的定義,具體如下圖所示:

在這裏插入圖片描述
可以看到屏幕座標系的起始點(0,0)在左上角,而標準座標系的起始點在canvas中心處.

  • 假設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);

反過來,如果要求出物體響應的屏幕座標,世界座標->標準座標->屏幕座標,那麼可以這樣:

// 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);
  • 假設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);
發佈了376 篇原創文章 · 獲贊 1037 · 訪問量 243萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章