【问题标题】:Finding the polygon in a 2D mesh which contains a point在包含点的 2D 网格中查找多边形
【发布时间】:2013-01-09 19:28:02
【问题描述】:

我有一个 3D 多边形网格和一个相应的 2D 多边形网格(实际上来自 UV map),我用它们将几何图形映射到 2D 平面上。给定平面上的一个点,我如何有效地找到它所在的多边形,以便将该 2D 点映射回 3D?

我能想到的最佳方法是将多边形存储在 2D 区间树中,并使用它来获取候选多边形。有没有更简单的方法?

澄清一下,这不适用于着色器。我实际上是在进行 2D 物理模拟并将其渲染为围绕 3D 网格。为了绘制每个对象,我需要弄清楚 3D 中的哪个点对应于它的真实 2D 位置。*

【问题讨论】:

    标签: computational-geometry


    【解决方案1】:

    我见过的三角形网格的一种方法如下:选择一个三角形,并想象每个边定义一个半空间。对于给定的边,半空间边界是包含边的线,而半空间不包含三角形。选择一条边,其对应的半空间包含您的目标点。然后选择边缘另一侧的三角形,重复该过程。

    使用此方法,您最终将到达包含目标点的三角形。

    这个方法可以说比实现二维区间树更简单,尽管搜索效率较低(如果n 是三角形的数量,它是 O(√n) 而不是 O(log n)。此外,它应该适用于多边形网格,只要多边形是凸的。

    【讨论】:

    • 谢谢,我想过做这样的事情来更新每一帧的新位置,考虑到事情通常不会在一帧中移动很远,这会很好。不幸的是,我的网格可能是凹的或有孔的,所以我最终可能不得不使用某种空间划分树,为了简单起见,我考虑的是四叉树而不是二维间隔树。
    • @Henk,当你说你的网格可以是凹的或有孔的时候,你是指多边形吗?
    【解决方案2】:

    所以,如果我只是想实现这个东西,我可能会从所有三角形的全局搜索开始 - 计算每个三角形的那个 2d 点的重心坐标,找到所有重心坐标的三角形正,然后使用它们映射到 3d(将 stu 位置乘以 3d 点)。我会先做这个,只有当它不够快时我才会尝试更复杂的东西。

    如果可以通过三角形而不是二维点进行迭代,那么重心方法可能会足够快。但是您似乎在任意位置有一堆二维点需要映射,并且这些点的位置会随着帧的变化而变化?

    如果您遇到这种情况,您可能会通过实现每帧的本地更新来获得很大的加速。每个 2d 点都会记住它在哪个三角形内。将其设置为当前三角形。测试新位置是否在当前三角形内。如果不是,那么您希望将网格移动到最接近目标 2d 点的相邻三角形。每个边相邻三角形由边上的两个公共点加上另一个点组成。找出哪个边相邻三角形的另一个点最接近目标,并将其设置为当前。然后迭代 - 似乎它应该很快找到它?您还可以为每个三角形缓存一个最大尺寸,因此如果该点移动了很多,您可以迭代到下一个邻居而不进行重心计算(最大尺寸需要是距离,如果您比那个更远与任何三角形点的距离,您不可能在三角形内。这是最大边的长度。

    但正如您在 cmets 中提到的,您可能会遇到具有凹面、孔或单独连接组件的网格的问题,您可能会陷入局部最小值。有几种方法可以解决这个问题。我认为最简单的方法是保留所有访问过的三角形的列表(可能作为三角形上的标志,vector 或 set)并拒绝重新访问三角形。如果您发现您已经访问了当前三角形的所有邻居,则回退到全局搜索。此类失败可能并不常见,因此不会对您的表现造成太大影响。

    这种每帧更新可以非常快,甚至可能是计算初始包含三角形的一种不错的方法 - 只需选择一个随机三角形并从那里步行(从检查所有 n 个三角形更改为只检查那些与目标大致成直线)。如果速度不够快,您可以做的是保留 2d 网格点的 k-d 树(或类似的东西)以及每个网格点的单个接触三角形索引。种子迭代,在k-d树中找到离目标2d点最近的点,将相邻三角形设置为当前,然后进行迭代。

    【讨论】:

      猜你喜欢
      • 2018-02-14
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      相关资源
      最近更新 更多