2017-06-03 87 views
0

我使用Three.js呈現從服務器檢索到的點雲數據。使用用戶鼠標點擊點雲到點雲

對於每個數據集,我循環遍歷數據點並創建一個Three.js Vector3對象,其中每個數據點對應的x,y值爲z。我將每個頂點都推送到一個列表中,然後將其傳遞到我的點組件中的幾何組件的頂點支柱中。

render() { 
    this.pointCloudVertices = []; 
    if (this.props.points) { 
     const points = this.props.points 
     for (let i = 0; i < points.x.length; i++) { 
      const vertex = new THREE.Vector3(); 

      vertex.x = points.x[i] 
      vertex.y = points.y[i] 
      vertex.z = points.z[i] 

      this.pointCloudVertices.push(vertex); 
     } 
    } 
    return (<points> 
     <geometry vertices={this.pointCloudVertices}/> 
     <pointsMaterial 
      color={ (Math.floor(Math.random()*16777215)) } 
      size={ 0.2 } 
     /> 
    </points>); 
} 

https://github.com/caseysiebel/pc-client/blob/master/src/components/PointCloud.js

我希望用戶能夠使用他們的鼠標點擊畫布裏面添加點到另一個點雲(點組成)。

我發現了很多指向Three.js'Raycaster的資源,但是這個工具似乎更適用於選擇已經在畫布中的對象。在我的情況下,我希望用戶能夠點擊並且未被對象佔據的區域,讓客戶端計算出該點擊的x,y座標,然後添加一個頂點,使用這些x/y/z值,直到用戶通過此模式添加點爲止的點分量(可能爲空)。

我對將如何將2D鼠標事件轉換爲3D頂點值有點困惑。如果有人知道這個問題有什麼好的資源,我很樂意檢查它們。

+1

「我有點困惑,我將如何將2D鼠標事件轉換爲3D頂點值」新THREE.Vector(mouseX,mouseY,0)'是最簡單的解決方案,雖然可能不滿意。我想說,在這一點上,這比數學更像是一個設計問題。 **你想**這個2D平面轉換成3D空間嗎?想象一下,你坐在你的客廳裏,沙發上,指着某個方向。你想在哪裏添加這一點?特別是在什麼深度/距離你?如何決定第一點(s)?如何爲後面的? – Thomas

+0

感謝您的回覆。根據你的評論,我認爲這裏有兩個問題。如果我在2D平面上選擇一個點,你是對的,我真的定義了一條從我坐的位置(相機位置)沿着無限延伸的第三軸延伸出來的光線。我希望我的新觀點坐在這條線上的問題是一個設計問題。如何將相機的當前位置和由數據集定義的原點轉換爲我正在查看的平面是數學問題。 – Casey

+0

在數學部分,攝像機的[projectionMatrix](https://threejs.org/docs/#api/cameras/Camera.projectionMatrix)應該是您在確定射線時感興趣的那個;但已經過了一段時間,我做了THREE.js – Thomas

回答

1

隨着THREE.Raycaster(),我看到幾個解決方案:

使用.ray屬性的.at()方法。就像這樣:

raycaster.ray.at(100 + Math.random() * 150, rndPoint); 

在這裏你可以設置限制從光線的原點的距離,它看起來像這樣從原來的相機:

front camera view

,以及它將如何看起來像從側面:

free camera view

jsfiddle例子。你可以在那裏切換線路。

2.使用.intersectObjects()方法。相交對象是約束的平面。例如,我們有立方體形式的飛機。當我們通過它們投射光線時,我們總是交叉兩個平面,並且交叉點對象數組的對象將按照距光線原點的距離排序。因此,此陣列中的第一個元素將是最接近的平面。所以,當我們知道它時,我們可以得到它們的交點,並從點2得到一個新的矢量(它的長度和方向)。然後,我們就設置在沿向量的隨機位置點從點1點2

intersected = raycaster.intersectObjects(planes.children); 
    if (intersected.length > 0){ 
    var point1 = intersected[0].point; 
    var point2 = intersected[1].point; 
    var diff = point2.clone().sub(point1); 
    var diffLength = diff.length(); 
    rndPoint = point1.clone().addScaledVector(diff.normalize(), Math.random() * diffLength); 
    . . . 
    } 

它看起來像這樣從前置攝像頭:

front camera view

,並從一旁:

​​

例如

jsfiddle。線也可以在這裏切換。您可以使用THREE.Raycaster() with THREE.OrthographicCamera()。這是更簡單)