2017-06-03 90 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()。这是更简单)