使用用户鼠标单击将点添加到点云

时间:2017-06-03 20:12:02

标签: javascript reactjs canvas 3d three.js

我正在使用Three.js渲染从服务器检索的点云数据。

对于每个数据集,我遍历数据点并使用x,y和amp;创建一个Three.js Vector3对象。 z值对应于每个数据点。我将每个顶点推到一个列表上,然后我将其传递到我的点组件中的几何组件的顶点prop。

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和amp; z点击该坐标,然后将具有这些x / y / z值的顶点添加到点组件(可能为空,直到用户通过此模态添加点数)。

我对如何将2D鼠标事件转换为3D顶点值感到困惑。如果有人知道关于这个主题的任何好资源,我很乐意检查出来。

1 个答案:

答案 0 :(得分:1)

使用THREE.Raycaster(),我看到了几个解决方案:

1。使用.ray属性的.at()方法。像这样:

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

在这里,您可以设置距离光源原点的距离约束,它将从原始相机中看起来像这样:

front camera view

以及从旁边看起来如何:

free camera view

jsfiddle示例。你可以在那里切换线路。

2。使用.intersectObjects()方法。交叉对象是约束平面。例如,我们有一个立方体形式的飞机。当我们通过它们投射光线时,我们总是与两个平面相交,并且将根据与光线原点的距离对intersectec对象的数组进行排序。因此,该数组中的第一个元素将是最近的平面。所以,当我们知道它时,我们可以从 point2 获取它们的交点和sub point1 ,得到一个新的向量(它的长度和方向)。然后我们将在 point1 point2 的向量的随机位置设置一个点:

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

从旁边:

free camera view

jsfiddle示例。线也可以在这里切换。

或者您可以使用THREE.Raycaster() with THREE.OrthographicCamera()。哪个更简单)