【问题标题】:Algorithm for determining whether a point is inside a 3D mesh确定点是否在 3D 网格内的算法
【发布时间】:2011-09-27 02:43:24
【问题描述】:

确定一个点是否在 3D 网格内的快速算法是什么?为简单起见,您可以假设网格都是三角形且没有孔。

到目前为止,我所知道的是,确定光线是否穿过网格的一种流行方法是计算光线/三角形相交的数量。它必须很快,因为我将它用于触觉医学模拟。所以我不能测试所有三角形的光线相交。我需要某种散列或树数据结构来存储三角形,以帮助确定哪个三角形是相关的。

另外,我知道如果我有任何顶点的任意二维投影,那么简单的点/三角形相交测试都是必要的。但是,我仍然需要知道哪些三角形是相关的,此外,哪些三角形位于点前面并且只测试这些三角形。

【问题讨论】:

  • 杰夫我看到你的方法来检查一个点是否在网格内。在获得每个三角形的 AABB 后,如何按照您所说的进行 Hash 步骤?每个 tri 的 AABB 是 (xmin, xmax, ymin, ymax, zmin, zmax),那么生成的哈希值呢?超

标签: algorithm intersection mesh point


【解决方案1】:

我解决了自己的问题。基本上,我采用任意二维投影(丢弃其中一个坐标),并将三角形的 AABB(轴对齐边界框)散列到二维数组中。 (titus 提到的一组 3D 立方体是多余的,因为它只会给你一个常数因子加速。)使用 2D 数组和你正在测试的点的 2D 投影来获得一小组三角形,你可以这样做在(参见Intersections of Rays, Segments, Planes and Triangles in 3D)上进行 3D 射线/三角形相交测试,并计算 z 坐标(抛出的坐标)大于该点的 z 坐标的射线相交的三角形数量。偶数个交叉点意味着它在网格之外。奇数个交叉点意味着它在网格内。这种方法不仅速度快,而且很容易实现(这正是我想要的)。

【讨论】:

  • 如果我理解正确的话,射线测试的方向是选择的 2D 投影的方向?
  • 当光线与三角形的顶点或边相交时,你会怎么做?你没有得到错误的交叉口数量吗?
  • 如果您精确地碰到边或顶点,则必须检查所有参与三角形的表面法线(实际上是它们在方向分量中的值的符号)。更普通的解决方案可能是选择另一个坐标方向(如果您有相应的哈希表可用)或在原始点上添加小的扭曲并进行多数投票。
  • 我实现了类似的东西。有不同光栅化器的三种参考实现。 github.com/3DStuff/voxelizer
  • 算法的复杂度是多少?
【解决方案2】:

只有当您有许多查询来证明构建数据结构的时间是合理的时,这种算法才有效。

将空间分成大小相等的立方体(我们稍后会计算出大小)。对于每个立方体,知道哪些三角形中至少有一个点。丢弃不包含任何东西的立方体。执行 wikipedia 上提供的光线投射算法,而不是测试线是否与每个三角形相交,获取与线相交的所有立方体,然后仅对这些立方体中的三角形进行射线投射。注意不要多次测试同一个三角形,因为它存在于两个立方体中。
找到合适的立方体尺寸很棘手,它不应该太大或太小。它只能通过反复试验才能找到。 假设number of cubescnumber of trianglest
立方体中三角形的平均数是 t/c
k 是与射线相交的立方体的平均数
这些立方体中的线立方体交点 + 线三角形交点必须最小
c+k*t/c=minimal => c=sqrt(t*k)
您必须测试立方体大小的值,直到 c=sqrt(t*k) 为真
立方体大小的一个很好的开始猜测是sqrt(mesh width)
有一些观点,对于 1M 三角形,您将按 1k 交叉点的顺序进行测试

【讨论】:

  • “做一个光线投射算法”,朝哪个方向?
  • @rwols: 任意方向,只要光线经过奇数个三角形,就在网格中。
【解决方案3】:

就准确性而言,Ray Triangle Intersection 似乎是一种很好的算法。 Wiki 有更多算法。我在这里链接它,但你可能已经看过了。

您能否即兴发挥,保持点与它们构成顶点的平面之间的关系矩阵?这个话题似乎是学术界的一个研究课题。不知道如何访问与此相关的更多讨论。

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 2020-09-07
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 2015-12-26
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多