将带孔的多边形转换为多个没有孔的简单多边形

时间:2017-07-14 06:54:26

标签: polygons

我正在处理IfcFace。我给了一个带孔的简单多边形,我需要将它转换成多个没有孔的简单多边形,以便CAD进一步处理它。一点点演示ilustration:

enter image description here

我最好的方法是进行受约束的delaunay三角剖分并将三角形重新加入更大的多边形。像这样: enter image description here 但是由于浮点精度和算法不稳定性,delaunay三角剖分甚至更多的约束部分往往因难以输入而失败。我的输入有时会生成高度为1e-8且基本长度为1的三角形。

是否有更好的更强大的算法来实现这种转换?

2 个答案:

答案 0 :(得分:1)

我认为形状的完整三角测量可以根据您的需要进行大量计算。并且三角测量还使三角形位于图形外部,甚至部分位于内部和部分外部,因此正确地重新组合它们也很复杂。

提案1

我想到了一种完全不同的方法 是否真的需要将图形分成2个数字才能在CAD程序中使用它?如果你可以将它描述为一个循环中的一个数字(一个形成多边形的点列表),我希望它也可以。
你需要的是找到连接图形的不同循环的线条,这些线条完全位于图形内部,以便您可以使用它们来组合循环。

我首先要比较不同循环的段对,然后搜索彼此最接近的段。 开始将外循环的所有段与所有内循环的所有段进行比较 实际上,我会通过将外循环上的点与内循环的段和内循环上的点与外循环的段进行比较来实现它。如果x或y距离大于已经找到的最小距离,我会通过跳过计算进行优化 2个段或彼此最接近的点和段将为您提供一条线,可用于组合环(或拆分图):从其中一个(或点)的一个角的线垂直于其他部分。缺点是您正在添加新节点,但它是高效且始终正确的 一旦找到这样的线,连接的内部循环和新的线/段可以组合在一个修改的外部循环中,其中包括新的段两次以关闭新循环。您可以通过比较修改后的外环的片段与其余的其他内环来重复该过程 当使用所有内部循环时,你有一个描述整个数字的循环。

要将数字完全拆分为2个数字,您需要多一个额外的部分 但我认为此时我们所拥有的循环可以在大多数CAD软件中用于表示您的数字。它不是一个标准化的数字,因为它触及自己,但CAD程序通常不关心它。它完全可用于CAD程序来表示图形的表面。

如果你真的想要将它完全分成2个数字,你可以通过搜索2个段来找到你需要的额外线条,或者如果你将比较限制为对的段和点,则可以找到更好的点和彼此最接近的线段环路中两个方向上已经添加的所有段都在环路中分开。所有添加的段在循环中都是两次,因此新循环中将始终有2个部分将被所有部分分开。

评论您对提案1的回答

我没有权利对您的回答发表评论,因为我没有足够的学分,所以我会将评论添加到我自己的答案中。

我正在看你的例子,我首先误解了这个,我改编了这个评论。

你有3个洞,所以算法的第一部分会添加你要显示的3个片段。

而且,是的,你显然对算法的第二部分有一个问题。你需要第4行但是在这种情况下没有2个部分,它们在两个方向上被所有3个增加的部分分开,或者我无论如何都不会立即看到它们。
我假设新循环中总有2个部分将由所有新段分隔。当有3个或更多洞时,这个假设是错误的。

但我会进一步思考它。

提案2

我现在正在考虑另一种可能的算法。

  1. 计算图中每个孔的表面。选择每个洞的一角。

  2. 在最小的2个孔的选定角落画一条线 它可以是任何2个孔,但是采用最小的孔可以增加用更少的线切割更多孔的机会 如果只留下一个洞,只需在你得到的一个点上划一条线。方向并不重要。我会选择在选定的点和最近的另一个点上绘制线条。

  3. 使用图形的线段检测绘制线条的所有交点,以将线条缩减为完全位于图形内部的一组线段,并连接图形的不同线圈。省略在同一循环中开始结束的任何段 如果仅在一个点上被找到的段触及一个孔。将一个段移动到最靠近该点的同一个孔的点,以避免结束具有接触外部的孔的图形。 检查修改后的段的新交叉点,如果找到则再次将其拆分 查找所有交叉点需要将找到的线与图中的所有线段进行比较,这也是很多计算,但是您可以通过在计算交点之前检查线是否穿过线段周围的边界框来跳过计算。我首先计算与外环的交点,以便尽快为该线的剩余部分设置一个边界框,因为这也有助于检查您不需要比较交叉点的部分。 /> 您还可以通过连接连接段的最近端点的段(如果尚未在2段的连接点中)替换每个找到的段来进行优化。这样做可以避免为新数字创建额外的点,并增加一步消除更多空洞的机会。但是,您需要再次检查新交叉点并重复此优化,直到找不到交叉点为止 还有一个可能的优化:检查尚未切割的孔的点是否接近找到的段并将找到的段拆分为2个段以在同一步骤中捕获该孔。就像之前的优化一样,这也需要再次检查新的交叉点。

  4. 使用细分将图形拆分为2个数字,并从步骤2开始重复每个仍然有洞的新图形。

  5. 缺点是你最终可能会得到超过2个数字(最大(n + 1)/ 2个数字,其中n是空洞的数量),但是如果你有很多洞导致许多数字,那么你可能会重新组合其中一些。

答案 1 :(得分:0)

我正在使用这个答案来形象化我对@Stefan Mondelaers的评论:

这就是我使用 约束 Delaunay三角测量的原因。但你是对的,我也觉得这太过分了。

可悲的是,CAD确实需要多个循环,因为循环中的所有点都必须是唯一的。

我认为算法的第二部分不起作用。

  

如果你真的想要将它完全分成2个数字,你可以通过搜索2个段来找到你需要的额外线条,或者如果你将比较限制为对的段和点,则可以找到更好的点和彼此最接近的线段环路中两个方向上已经添加的所有段都在环路中分开。所有添加的段在循环中都是两次,因此新循环中将始终有2个部分将被所有部分分开。

查看此示例,其中橙色是外部多边形,蓝色是其孔。算法的第一部分将执行此操作: enter image description here 但现在第二部分只会添加蓝色多边形之间的连接,因为它们最接近。但这不会解决持有橙色多边形的循环的问题,因为新引入的点将在那里两次。