合并许多凸多边形的快速算法或库
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 是边交叉点的数量。
【讨论】:
以上是关于合并许多凸多边形的快速算法或库的主要内容,如果未能解决你的问题,请参考以下文章