确定点是否位于 3D 网格内部的算法
用于确定点是否位于 3D 网格内部的快速算法是什么?为简单起见,您可以假设网格都是三角形并且没有孔。
到目前为止我所知道的是,确定光线是否穿过网格的一种流行方法是计算光线/三角形相交的数量。它必须很快,因为我正在使用它进行触觉医学模拟。所以我无法测试所有三角形的射线相交。我需要某种哈希或树数据结构来存储三角形,以帮助确定哪个三角形是相关的。
另外,我知道如果我有任意顶点的二维投影,则需要一个简单的点/三角形相交测试。但是,我仍然需要知道哪些三角形是相关的,此外,哪些三角形位于点前面,并且只测试这些三角形。
What is a fast algorithm for determining whether or not a point is inside a 3D mesh? For simplicity you can assume the mesh is all triangles and has no holes.
What I know so far is that one popular way of determining whether or not a ray has crossed a mesh is to count the number of ray/triangle intersections. It has to be fast because I am using it for a haptic medical simulation. So I cannot test all of the triangles for ray intersection. I need some kind of hashing or tree data structure to store the triangles in to help determine which triangle are relevant.
Also, I know that if I have any arbitrary 2D projection of the vertices, a simple point/triangle intersection test is all necessary. However, I'd still need to know which triangles are relevant and, in addition, which triangles lie in front of a the point and only test those triangles.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我解决了我自己的问题。基本上,我采用任意 2D 投影(扔掉其中一个坐标),并将三角形的 AABB(轴对齐边界框)散列到 2D 数组。 (titus 提到的一组 3D 立方体是多余的,因为它只能给你一个常数因子加速。)使用 2D 数组和你正在测试的点的 2D 投影来获得一小组三角形,你可以这样做3D 射线/三角形相交测试(请参阅相交3D 中的射线、线段、平面和三角形)并计算 z 坐标(抛出的坐标)大于点的 z 坐标的射线交点的三角形数量。偶数个交点意味着它在网格之外。奇数个交点意味着它在网格内部。这种方法不仅速度快,而且非常容易实现(这正是我所寻找的)。
I solved my own problem. Basically, I take an arbitrary 2D projection (throw out one of the coordinates), and hash the AABBs (Axis Aligned Bounding Boxes) of the triangles to a 2D array. (A set of 3D cubes as mentioned by titus is overkill, as it only gives you a constant factor speedup.) Use the 2D array and the 2D projection of the point you are testing to get a small set of triangles, which you do a 3D ray/triangle intersection test on (see Intersections of Rays, Segments, Planes and Triangles in 3D) and count the number of triangles the ray intersection where the z-coordinate (the coordinate thrown out) is greater than the z-coordinate of the point. An even number of intersections means it is outside the mesh. An odd number of intersections means it is inside the mesh. This method is not only fast, but very easy to implement (which is exactly what I was looking for).
仅当您有许多查询来证明构建数据结构的时间合理时,该算法才有效。
将空间分成大小相等的立方体(稍后我们会计算出大小)。对于每个立方体,知道哪些三角形至少有一个点。丢弃不含任何东西的立方体。按照维基百科上的介绍进行光线投射算法,但不是测试直线是否与每个三角形相交,而是获取与直线相交的所有立方体,然后仅对这些立方体中的三角形进行光线投射。注意不要多次测试同一个三角形,因为它存在于两个立方体中。
找到合适的立方体尺寸很棘手,它不应该太大或太小。它只能通过反复试验才能找到。
假设
立方体数量
为c
,三角形数量
为t
。立方体中三角形的平均数量为
t/c
k
是与射线相交的立方体的平均数量这些立方体中的线-立方体相交 + 线-三角形相交必须最小
c+k*t/c=minimal
=>c=sqrt(t*k)
您必须测试立方体大小的值,直到
c=sqrt(t*k)
为 true对于立方体大小的一个很好的起始猜测是
sqrt(mesh width)
为了获得一些视角,对于 1M 个三角形,您将按 1k 个交叉点的顺序进行测试
This is algorithm is efficient only if you have many queries to justify the time for constructing the data structure.
Divide the space into cubes of equal size (we'll figure out the size later). For each cube know which triangles has at least a point in it. Discard the cubes that don't contain anything. Do a ray casting algorithm as presented on wikipedia, but instead o testing if the line intersects each triangle, get all the cubes that intersect with the line, and then do ray casting only with the triangles in these cubes. Watch out not to test the same triangle more than one time because it is present in two cubes.
Finding the proper cube size is tricky, it shouldn't be neither to big or too small. It can only be found by trial and error.
Let's say
number of cubes
isc
andnumber of triangles
ist
.The mean number of triangles in a cube is
t/c
k
is mean number of cubes that intersect the rayline-cube intersections + line-triangle intersection in those cubes has to be minimal
c+k*t/c=minimal
=>c=sqrt(t*k)
You'll have to test out values for the size of the cubes until
c=sqrt(t*k)
is trueA good starting guess for the size of the cube would be
sqrt(mesh width)
To have some perspective, for 1M triangles you'll test on the order of 1k intersections
我没有从 mesh_contains 得到结果
我使用从修剪网格获取交点
locations, index_ray, index_tri = Mesh.ray.intersects_location( ray_origins=ray_origins, ray_directions=ray_directions,multiple_hits=True)
和
mesh_contains 内网格内的检查点,点和三角形已缩放
我可以知道缩放的原因吗
I am not getting the result from mesh_contains
I get intersection points from trimesh using
locations, index_ray, index_tri = Mesh.ray.intersects_location( ray_origins=ray_origins, ray_directions=ray_directions,multiple_hits=True)
and check point inside mesh
inside mesh_contains points and triangls are scaled
can i know the reason of scaling
就准确性而言,射线三角形交集似乎是一个很好的算法。 Wiki 还有更多算法。我将其链接到此处,但您可能已经看到了。
您能否即兴维护点和它们作为顶点的平面之间的关系矩阵?这个主题似乎是学术界研究的一个话题。不知道如何访问与此相关的更多讨论。
Ray Triangle Intersection appears to be a good algorithm when it comes to accuracy. The Wiki has some more algorithms. I am linking it here, but you might have seen this already.
Can you, perhaps improvise by, maintaining a matrix of relationship between the points and the plane to which they make the vertices? This subject appears to be a topic of investigation in the academia. Not sure how to access more discussions related to this.