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

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

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

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

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

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

有什么建议吗?

==== 编辑 ====

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

【问题讨论】:

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

标签: polygon computational-geometry


【解决方案1】:

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

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2012-08-04
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 2021-02-02
    • 2013-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    相关资源
    最近更新 更多