简体   繁体   English

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

[英]Add Points to a Point Cloud with User Mouse Clicks

I'm using Three.js to render point cloud data retrieved from a server. 我正在使用Three.js渲染从服务器检索的点云数据。

For each data set, I loop over the data points and create a Three.js Vector3 object with x, y & z values corresponding to each data point. 对于每个数据集,我遍历数据点并创建一个Three.js Vector3对象,该对象的x,y和z值与每个数据点相对应。 I push each of these vertices onto a list which I then pass into the vertices prop of my geometry component within my points component. 我将这些顶点中的每一个推到一个列表中,然后将其传递到我的点组件中的几何组件的顶点道具中。

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 https://github.com/caseysiebel/pc-client/blob/master/src/components/PointCloud.js

I'd like the user to be able to use their mouse to add points to another point cloud (points component) by clicking inside the canvas. 我希望用户能够通过单击画布内部的鼠标来将点添加到另一个点云(点组件)。

I found a lot of resources pointing to the Three.js' Raycaster, but this tool seems to be more for selecting out objects already in the canvas. 我发现有很多资源指向Three.js的Raycaster,但是该工具似乎更多用于选择画布中已有的对象。 In my case I'd like the user to be able to click on and area in the canvas not occupied by an object, have the client work out the x, y & z coordinates of that click and then add a vertex, with those x/y/z values, to a points component (likely empty until the user adds points via this modality). 在我的情况下,我希望用户能够单击画布上未被对象占用的区域,让客户端计算出该单击的x,y和z坐标,然后添加具有这些x的顶点/ y / z值添加到点组件(在用户通过此方式添加点之前可能为空)。

I'm a little confused as to how I will convert 2D mouse events into a 3D vertex value. 对于如何将2D鼠标事件转换为3D顶点值,我有些困惑。 If anyone knows any good resources on this subject I'd love to check them out. 如果有人知道关于此主题的任何有用资源,我很乐意将其检查出来。

With THREE.Raycaster() , I see several solutions: 通过THREE.Raycaster() ,我看到了几种解决方案:

1. Use the .at() method of the .ray property. 1.使用.ray属性的.ray .at()方法。 Like this: 像这样:

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

Here you can set the constraints for the distance from the origin of the ray, and it will look like this from your original camera: 在这里,您可以设置到射线原点的距离的约束,从原始相机看,它看起来像这样:

前置摄像头视图

and how it will look like from aside: 以及从侧面看的样子:

免费的相机视图

jsfiddle example. jsfiddle示例。 You can switch the lines off there. 您可以在此处关闭线路。

2. Use the .intersectObjects() method. 2.使用.intersectObjects()方法。 Where intersecting objects are planes of constraints. 相交的对象是约束平面。 For example, we have planes in the form of a cube. 例如,我们有一个立方体形式的平面。 When we cast a ray through them, we always intersect two planes, and the array of intersectec objects will be sorted by distance from the origin of the ray. 当我们通过它们投射光线时,我们总是与两个平面相交,而相交对象的阵列将按距光线原点的距离排序。 Thus the first element in this array will be the closest plane. 因此,此数组中的第一个元素将是最近的平面。 So, when we know it, we can take their points of intersection and sub point1 from point2 , getting a new vector (its length and direction). 因此,当我们知道时,我们可以从point2取得它们的交点和subpoint1的子点,从而获得一个新的矢量(其长度和方向)。 And then we'll just set a point at a random place along the vector from point1 to point2 : 然后我们沿着向量从point1point2在随机位置上设置一个点:

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);
    . . .
  }

It will look like this from the front camera: 从前置摄像头看起来像这样:

前置摄像头视图

and from aside: 从侧面:

免费的相机视图

jsfiddle example. jsfiddle示例。 Lines are switchable here too. 线路也可以在这里切换。

Or you can use THREE.Raycaster() with THREE.OrthographicCamera() . 或者,您可以将THREE.Raycaster()THREE.OrthographicCamera() Which is simplier ) 哪个更简单)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM