Search code examples
pythoncollision-detectionintersectionpoint-clouds

How can I detect a intersection between a pointcloud and a triangle mesh?


I have a point cloud with some objections and I generate a cuboid and want to detect a intersection/collision between the cuboid and the objects from the point cloud.

At the moment I am using Open3D and read a point cloud (xyzrgb, .ply) from a stereo vision camera and generate a 3D geometry (closed triangle mesh).

How can I detect a intersection between the triangle mesh and any point from the point cloud? I think the simplest way is to check for every point of the point cloud if it lays within the mesh, but how can I do this?

from open3d import *

pcd = read_point_cloud("out.ply")
draw_geometries([pcd])

# print("Let\'s draw some primitives")
mesh_box = create_mesh_box(width=1.0, height=1.0, depth=1.0)
mesh_box.paint_uniform_color([0.9, 0.4, 0.1])
mesh_frame = create_mesh_coordinate_frame(size=0.6, origin=[0, 0, 0])
draw_geometries([pcd, mesh_box, mesh_frame])

TM = np.eye(4, dtype=int)
TM[0, 3] = 10
TM[1, 3] = 10
TM[2, 3] = 10

open3d.geometry.Geometry3D.transform(mesh_box, TM)
draw_geometries([pcd, mesh_box, mesh_frame])

Solution

  • There are three different scenarios I can see that may be applicable here:

    1. Point-Mesh epsilon-intersection Here we check if the points lie on the surface of the mesh.

    For all points performs a point-triangle distance check against all triangles of the mesh and check if the distance is smaller than some chosen epsilon.

    2. Point-Mesh collision detection Here we check if the points have collided with the mesh. This assumes the points have moved and thus we have a line segment from the last position to the current.

    For all point movements perform a line-triangle intersection against all triangles of the mesh.

    3. Point-Mesh containment Here we check if the points are inside the mesh. This assumes the mesh is closed and orientable. If it's not, you have an entirely different problem.

    For all points choose a random ray extending to infinity (or sufficiently far away) and calculate the number of intersections of that ray with the mesh. If it is zero or an even number, the point is on the outside of the mesh. Otherwise it's inside. Note that this algorithm might fail in some corner cases, for example if the point is directly on the surface of the mesh or the ray happens to intersect the mesh on a line instead of a point.

    Basically all scenarios boil down to performing point-triangle distance checks and line-triangle intersection checks. I could post some solutions for both these problems, but I'd just be copying results of a search query, so...