Javascript 通过用户鼠标单击将点添加到点云

Javascript 通过用户鼠标单击将点添加到点云,javascript,reactjs,canvas,3d,three.js,Javascript,Reactjs,Canvas,3d,Three.js,我正在使用Three.js渲染从服务器检索到的点云数据 对于每个数据集,我在数据点上循环并创建一个Three.js Vector3对象,其x、y和z值对应于每个数据点。我将这些顶点推到一个列表上,然后将其传递到我的点组件中的几何体组件的顶点属性中 render() { this.pointCloudVertices = []; if (this.props.points) { const points = this.props.points for

我正在使用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>);
}
render(){
this.pointCloudVertices=[];
如果(此.道具.点){
常量点=this.props.points
对于(设i=0;i

我希望用户能够通过单击画布内部,使用鼠标将点添加到另一个点云(点组件)

我找到了很多指向Three.js的Raycaster的资源,但是这个工具似乎更适合于选择画布中已经存在的对象。在我的例子中,我希望用户能够单击画布上没有被对象占据的区域,让客户端计算出该单击的x、y和z坐标,然后使用这些x/y/z值向点组件添加顶点(在用户通过该模式添加点之前可能为空)


对于如何将2D鼠标事件转换为3D顶点值,我有点困惑。如果有人知道这方面的好资源,我很乐意查看。

有了这些资源,我看到了几种解决方案:

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

raycaster.ray.at(100 + Math.random() * 150, rndPoint);
在这里,您可以设置与光线原点之间的距离的约束,从原始摄影机看,该距离如下所示:

从另一方面看,它将是什么样子:

例如。你可以在那里把线路关掉

2。使用
.intersectObjects()
方法。其中相交对象是约束平面。例如,我们有一个立方体形式的平面。当我们投射光线穿过它们时,我们总是与两个平面相交,相交对象的数组将按距离光线原点的距离排序。因此,此数组中的第一个元素将是最近的平面。所以,当我们知道它时,我们可以从点2取它们的交点和子点1,得到一个新的向量(它的长度和方向)。然后我们将沿着向量从点1到点2的任意位置设置一个点:

从前面的摄像头看,它将是这样的:

除此之外:

例如。这里的线路也可以切换


或者你可以使用。(哪一个更简单)

“我对如何将2D鼠标事件转换为3D顶点值感到有点困惑”
新的三个。向量(mouseX,mouseY,0)
将是最简单的解决方案,尽管可能并不令人满意。我想说,在这一点上,这更像是一个设计问题而不是数学问题。您希望如何将此二维平面转换为三维空间?想象你坐在客厅里,坐在沙发上,指着某个方向。您希望在何处添加此点?特别是在离你多深/多远的地方?如何确定第一点?后面的怎么样?谢谢你的回复。根据你的评论,我认为这里有两个问题。如果我在2D平面上选择一个点,你是对的,实际上我是在定义一条光线,从我坐的位置(相机位置)沿着第三个轴无限延伸。我想让我的新点沿着这条光线放置在哪里的问题是一个设计问题。摄像机的当前位置和由数据集定义的原点如何转换为我所观察的平面是一个数学问题;但是我已经做了三次了。js你能让用户旋转鼠标滚轮来设置投影光线中点的Z吗?也许初始Z可以是现有点的平均Z,或者与最近添加的点相同的Z。您使用什么类型的相机?
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);
    . . .
  }