无孔多边形联合

Posted

技术标签:

【中文标题】无孔多边形联合【英文标题】:polygon union without holes 【发布时间】:2011-10-14 05:46:04 【问题描述】:

我正在寻找一些相当简单的(我知道多边形联合不是一个简单的操作,但也许有人可以用一个相对简单的方法为我指出正确的方向)合并两个相交多边形的算法。多边形可以是没有孔的凹面,并且输出多边形中也不应该有孔。多边形以逆时针方式表示。我的意思是在图片上呈现。正如您所看到的,即使多边形联合中有一个洞,我在输出中也不需要它。输入多边形肯定没有孔。我认为没有漏洞应该更容易做,但我仍然不知道。

【问题讨论】:

我在这里发布了相同问题的答案:***.com/a/19475433/904679 【参考方案1】:

您可以进行如下操作:

首先,将多边形的所有交点添加到您的点集。

然后我会像graham scan algorithm 一样继续,但还有一个限制。

不要选择与前一行形成最大角度的点(请查看 graham scan 以了解我的意思 (*),而是选择与前一个多边形之一具有最高角度的点。

你会得到一个描述你的形状的信封(不是凸的)。

注意:

这类似于找到点的凸包。

例如graham scan algorithm 将帮助您找到 O (N*ln (N) 中的点集的凸包,其中 N 是点数。

查找凸包算法,你可以找到一些想法。

备注:

(*)来自***:

这个算法的第一步是找到最低的点 y 坐标。如果最低 y 坐标存在于多个点 在集合中,x 坐标最低的点 应选择候选人。将此点称为 P。这一步需要 O(n), 其中 n 是有问题的点数。

接下来,点集必须按 它们和点 P 与 x 轴的夹角。任何通用 排序算法适用于此,例如堆排序(其中 是 O(n log n))。为了加快计算速度,不 有必要计算这些点与 x轴;相反,计算这个角度的余弦就足够了:它 是相关域中的单调递减函数 (由于第一步,它是 0 到 180 度)并且可能是 用简单的算术计算。

在凸包算法中,您选择了与前边形成最大角度的角度点。

要“坚持”您之前的多边形,只需添加您必须选择之前存在的边的约束。

你取消了角度小于 180° 的限制

【讨论】:

不,示例中的结果不是凸的。 “选择角度最大的那个,它是前一个多边形的一部分”——我认为这还不清楚。你能详细说明一下吗?【参考方案2】:

我没有完整的答案,但我即将着手解决类似的问题。我认为有两个步骤相当重要。首先是在位于外边缘的某个多边形上找到一个点。其次是为所有顶点制作一个边界框列表,并查看其中哪些重叠。这意味着当您遍历顶点时,您不必对所有顶点进行测试,只需对那些您知道有可能相交的顶点进行测试(边界框问题是轻量级的)。

由于您现在有一个外部点,您现在可以遍历连接的点,直到检测到一个交叉点。如果你知道哪一边在里面,哪边在外面(你可能需要在第一个顶点上做一些工作才能知道这一点),你就知道在交叉点上走哪条路。那么这只是切换多边形的问题。

如果你想保持那个洞(我会这样做),这会变得更有趣,在这种情况下,我可能会确保我已经用完了所有相交的边界框。您也没有指定如果您的多边形根本不相交会发生什么。但这要么不理会它们(如果你期望一个多边形出来,这可能是一个问题)或者返回一个错误。

【讨论】:

【参考方案3】:
    删除位于另一个多边形内的多边形的所有顶点:http://paulbourke.net/geometry/insidepoly/ 选择一个保证在联合多边形中的起点(极端情况之一可行) 以逆时针方式跟踪多边形的边缘。这些是您工会中的要点。一直追踪直到遇到交叉点(请注意,一条边可能与另一个多边形的不止一条边相交)。 找到第一个交叉点(如果有多个)。这是您联盟中的一个要点。 使用另一个多边形返回步骤 3。下一个点应该是与前一个边缘形成最大角度的点。

【讨论】:

您的解决方案很棒,但我仍然有一个问题边缘,我应该“跳转”到与当前边缘在同一条线上的其他多边形。我不确定如何选择应该遵循哪条边,因为有时应该遵循第二个多边形的边缘,有时应该遵循第一个。

以上是关于无孔多边形联合的主要内容,如果未能解决你的问题,请参考以下文章

使用 boost 的多边形联合

Boost 多边形联合结果在 windows 和 linux 之间是不同的

ArcGIS10.2联合和合并有啥区别和联系?

Three.js 多边形三角剖分在伪重复点中失败

如何组合复杂的多边形?

多多边形地理并集的高效计算技术