【问题标题】:Splitting a polygon into parts将多边形分割成多个部分
【发布时间】:2020-02-08 16:50:04
【问题描述】:

在我的应用程序中,我使用 OpenGL 和大量数据。

我需要做的一件事是收到多个可以是凸面或凹面的“简单”多边形。简单地说,我的意思是几何定义 - 没有孔和相交边缘的多边形。

我以点(顶点)的链接循环的形式收到这个 poligon,其中每个 Vi 都连接到 Vi-1 和 Vi+1 点,仅此而已。最后一点也连接到第一个点,结果给我们一个循环。

我现在要说的是我找到了多边形三角剖分,它就像一个魅力(我现在使用耳夹法)。

但是,我需要构建大量这些多边形,数百万个。为了尽量减少负载,我决定将我的世界分成“块”,就像 Minecraft 中的正方形。然后我使用平截头体剔除和其他优化方法来渲染或丢弃/简化其中的这些块和网格。

所以,我想做的是:如果我收到的多边形位于几个不同的块中 - 那么我想将它分成每个块的网格。基本上,我想创建多个在块边界上划分的多边形,然后对它们进行三角剖分并创建网格进行渲染。

因此,我想要一个(或多个)轮廓,然后我可以对其进行三角测量。

这是我的任务图片:

我自己做了一个算法来分割它,我认为它会起作用,但我发现它只有在任何给定块中的轮廓不分解时才有效,就像你在示例中看到的那样(换句话说,如果只有任何给定块中的一个数字)。

我想在这里问是否有人知道该任务的任何好的算法?我自己可能会想出一些东西,但实践表明,几乎总是有更好、更简单的现成解决方案。如果有人能给我一个有用的链接或一篇文章,我真的很感激,如果没有解决方案本身,那么可以提供一些想法。

【问题讨论】:

  • @genpfault,建议的副本回答这个问题。那里选择的答案甚至没有给出如何这些步骤是如何实现的示例。这个问题还有一个额外的要求,即裁剪后生成的多边形是分离的。这对某些人来说可能是微不足道的一步,但回答 this 问题仍需要更多信息。

标签: java opengl split polygon


【解决方案1】:

这是在编写一些可能有效的伪代码时的暗中尝试。如果可行,请随意实施它并使用实际代码选择您自己的答案。


首先,将顶点数组转换为从最后一个元素循环到第一个元素的双链表。或者将其建模为无向图可能会更好,因为一个点可能缺少邻居。

然后对每个象限应用以下算法,每次都从完整的多边形开始。您可以通过剔除象限之外的顶点来减小该多边形的大小并且距离与切割线相交的边缘至少 1 个相邻。

// We need to keep track of the points that we insert on the cutting lines
let LIX = List of X-Cut-Line Intersection Points
let LIY = List of Y-Cut-Line Intersection Points

foreach Edge AB in Poly where A is inside the quadrant, B outside
    // Insert points into the polygon that intersect the X-Cut-Line
    if AB Intersects X-Cut-Line
        let Ix = Intersection Point
        Insert Ix between AB so that A<->B becomes A<->Ix
        B can be removed from the polygon now
        Add Ix to LIX
    // Insert points into the polygon that intersect the Y-Cut-Line
    if AB.Intersects Y-Cut-Line
        let Iy = Intersection Point
        Insert Iy between AB so that A<->B becomes A<->Iy
        B can be removed from the polygon now
        Add Iy to LIY

// Then iterate pairs of points along each cutting line to join them
sort LIX by X Ascending
while (LIX.Length > 0)
    let P0 = LIX[0]
    let P1 = LIX[1]
    Link P0 and P1
    Remove P0 and P1 from LIX

sort LIY by Y Ascending
while (LIY.Length > 0)
    let P0 = LIY[0]
    let P1 = LIY[1]
    Link P0 and P1
    Remove P0 and P1 from LIY

最后,您可以在生成的链表/图形中查找循环以找到新的多边形。每个循环理论上不应包含已检测到的其他循环中的点,因此它是一个单独的多边形。

【讨论】:

  • 我第一次尝试处理这个问题时遇到了类似的情况。问题是 - 这个算法并不能很好地处理角落,并且(我认为)对于我们在块内有几个单独的多边形片段没有链接在一起的情况也不起作用。
  • @VladKozmyuk,最后一步(不是用伪代码编写的)是在结果图/链表中查找单个循环。这将负责识别单独的部分。对于角,您是指位于 X 和 Y 切割线上的点吗?
【解决方案2】:

我现在不在工作,因为是周末,所以我会在星期一尝试/测试这些东西。

然而,我目前想出的是一个非常简单的解决方案。

  1. 测试轮廓中的所有点。

  2. 如果点i 和点i+1 不属于同一个块(我可以轻松测试):

  3. 然后找到块边界与这两点所形成的线之间的交点。

  4. 将此新点添加到原始两点之间的轮廓中。

  5. 当多边形的每条边都被这样测试时 - 对其进行三角测量。

  6. 因为我们在块的边缘有点 - 那么在三角剖分过程中,三角形将完全适合块的边界

  7. 对于每个三角形,决定它属于哪个块并在那个块中生成网格。

我不会详细介绍一些优化想法 - 例如,如果整个图形适合同一块,则不需要评估生成的三角形。

【讨论】:

  • 试过了,这也不能很好地处理块角。
猜你喜欢
  • 2023-04-08
  • 2020-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多