How to detect if the points intersect to the plane?

Hello, everyone

I investigated a feature that can free-select point cloud; however, it is not working well while the camera is rotated, so I would like to ask whether Raycaster can be used in my case.

I collected the mouse coordinates and created a shape.

     let planeMeshGeometry = new THREE.ShapeBufferGeometry(shape);
     let line = new THREE.Mesh(planeMeshGeometry, new THREE.MeshBasicMaterial({
            color: new THREE.Color(color),
            transparent: true,
            opacity: 0.5,
            side: THREE.DoubleSide
            //linewidth: 10
        }));

     line.linewidth = 20;
     return line;

and some points are at the front side and back side of the plane

is it possible to determine those points located at the front and back?
I hope the plane I draw works like a frustum, but I am unsure whether it is possible.

You can create an instance of THREE.Plane by picking three vertices of your shape and then use setFromCoplanarPoints().

You can then use distanceToPoint() to compute the signed distance to a 3D point. The sign will tell you in what half space the point lies (before or behind the front of the plane).

1 Like

Thanks for your reply. Sorry, I did not explain well.

I actually would like to get those points that overlap the plane(in vision). But maybe your approach is also able to achieve this goal. If it is, then I need to think about how to get three points from the plane, it is actually an array of coordinates of mouse points down the path.

So in the other word, I would like to know if the points are located within the plane region like we can use a frustum and using “containsPoint” to determine whether the point in the rectangle shape

I was trying using each point as a origin of raycaster, direction to the camera, but the raycast return nothing intersection of point’s ray and plane …

Does this demo do what you need:

1 Like

Exactly, thanks for the information, I will learn how it works in your implementation

I tried to go through each point like your object and calculate the ray, the origin point is set as the point position. the ray is subVector from dot vector3 to the camera position. After I draw a mesh in between the points, somehow the intersection length is still zero.

    let umapRaycaster = new THREE.Raycaster();
    let selectionArea = clusterScene.scene.getObjectByName("drawPath");
    if (selectionArea) {
        for (let i = 0; i < clusters.info.length; i++) {

            let key = clusters.info[i].key;
            var cluster = uMap.data.filter((x) => x[1] === key);

            if (cluster === 0) { continue; }

            let ray = new THREE.Vector3();
            for (let j = 0; j < cluster.length; j++) {

                let dot = new THREE.Vector3(cluster[j][2] / 10, cluster[j][3] / 10, cluster[j][4] / 10);

                ray.subVectors(dot, clusterScene.camera.position).normalize();
                umapRaycaster.set(clusterScene.camera.position, ray);
                                
                let intersect = umapRaycaster.intersectObject(selectionArea);
                
                if (intersect.length > 0 && intersect[0].object == selectionArea) {
                    console.info("intersected");
                }

            }
        }
    }

I believe your implemenation is correct and match what I need, the different between yours and my is object, I am using point cloud and mesh, do you know what I missed?

I added a arrow helper to see the ray

Would it be possible to make a CodePen with some minimal (simplified) example? Like, a yellow mesh, a point cloud of 2 points (one infront and one behind the mesh)?

By looking at the code below, it is hard to tell whether the problem is that there is no intersection with SelectionArea because some parameter is wrong, or because the area is a group and you do not intersect recursively, or because some other objects is intersected before the area, so it is not in intersected[0]:

Such onine editable example would make it possible to debug. Otherwise it is like repairing a car by looking at photos and no touching at all.

I reproduced the code in the codepan, hope this is helpful to make you understand my question easier.

initially, I set control,enableRotate = false, so you can draw to select directly, after the mouse pointer up, I go through each point to detect whether the point insection with the mesh, but it seems not.

I think something with your algorithm is messed up. Here is what I tried:

  • Before intersecting I changed the color of selectionArea in order to see what mesh is used for raycasting. The result was that the selection did not change its color, so the code is not raycasting to the selection and thus the result is always 0
  • Then I looked at how the selection area is defined, and it is searched by name drawPath. You use getObjectByName and according to the documentation it “returns the first with a matching name.
  • Unfortunately, your scene is bloated with numerous objects called drawPath – most likely you create a new drawPath for every mouse move, thus only the very first drawPath is used by the raycaster.

Here is a snapshot of the scene contents, there is one umap and 72 drawPaths:

My suggestion is first to clear up the algorithm, so that there is only one drawPath and it is the latest shape.

Thanks for looking into the codepan. Somehow the

    let drawPathLine = scene.getObjectByName("drawPath");
    if (drawPathLine) {
      scene.remove(drawPathLine);
    }

did not work when the mouse point up event triggered. I change it to the mouse moving event and it works again. After drawing a selection plan, only one drawPth in the scene.

I made a few changes in the intersection ray calculation. It seams that it correctly finds how many points are selected with the mouse (the number is printed in the console).

Here is the modified version:

https://codepen.io/boytchev/pen/NWOMrxW?editors=0011

Thank you so much for looking into the code and making it works!

I read the modified code line by line to ensure do not miss any changes. I realized what you mean in the previous reply! Each mouse pressed moving, the raycaster is only available for the first object, so I need to keep removing the object from the last moving!

Thank you once again for helping!

1 Like