合并许多凸多边形的快速算法或库

Posted

技术标签:

【中文标题】合并许多凸多边形的快速算法或库【英文标题】:Fast algorithm or library to union many convex polygons 【发布时间】:2015-11-03 13:39:46 【问题描述】:

我需要对许多凸多边形(多达数万个)应用布尔 OR 运算(也称为联合),每个多边形的顶点少于 100 个。我尝试了 Boost.Geometry(boost::geometry::union_() 函数),它需要大约 200 毫秒来合并 1500 个多边形。

我已经实现了一个简单的优化:

    将多边形分成两组, 递归地将两个组合并为两个多边形集, 合并最后两个多边形集。

这种优化比逐个合并多边形快约 10 倍。

我需要一个算法或一个 C/C++ 库来在大约 10 毫秒内完成这样的操作。

有什么建议吗?

==== 编辑 ====

我已经用 Clipper (http://www.angusj.com/delphi/clipper.php) 替换了 Boost.Geometry,它满足了我的要求。 Clipper 可以在一次操作中合并多个多边形(Boost.Geometry 一次只能合并两个),这可能是它比 Boost.Geometry 快得多的原因。

【问题讨论】:

你已经对算法进行了并行化了吗? @NicoSchertler 尝试并行化算法,改进可以忽略不计 你确定吗?你是如何实现的? 1500 个多边形的 20 毫秒是一个非常不错的性能! @user416983,您可以将编辑移动到答案中。您可以回答自己的问题。似乎这种情况(您自己想出答案)是您被允许的完美示例。 【参考方案1】:

您可以尝试使用扫描线算法一次性处理所有多边形。

将所有边自上而下定位,并按顶部顶点的纵坐标自上而下排序。

维护一个活动列表,即所有穿过当前顶点的水平线的列表。对于线的位置,您可以确定与活动边的所有交点。保持活动边按交叉点的横坐标水平排序。

当您从一个顶点移动到下一个顶点时,一些边会进入列表,而其他边会离开。此外,在排序过程中,一些边可能会被交换,这表明它们相交。

交叉点成对出现,在多边形内追踪线段。沿水平方向合并所有线段是一个简单的一维问题。

将所有这些成分放在一起,通过将合并的输出从扫描线的一个位置链接到下一个位置,您将形成一个对应于最终联合的图形。它不一定是连接的。

应该可以将整个过程实现为单遍,并避免在不需要的地方分割边缘。

还要注意活动列表处理的组织方式,算法应该在 O(N Log(N) + NK) 的时间内运行,其中 K 是边交叉点的数量。

【讨论】:

以上是关于合并许多凸多边形的快速算法或库的主要内容,如果未能解决你的问题,请参考以下文章

排序算法之快速排序

混合快速/合并排序对随机数据的性能

为啥 Collections.sort 使用合并排序而不是快速排序?

python高级算法和数据结构:集合的快速查询与合并

快速排序(算法导论学习)

快速排序算法