Bentley-Ottmann算法的推广

时间:2010-11-18 09:05:37

标签: algorithm

Bentley-Ottmann算法用于确定线列表的交叉点。但是正如in Wiki所述,存在一些缺点:

  

该算法假设该行   段不是垂直的,那条线   段端点不会位于其他端点上   线段,那个过境点   仅由两个线段组成,并且   没有两个事件点有相同的   x坐标。但是,这些一般   位置假设不是   适用于大多数应用   线段交叉。

我的问题是,这种算法有一个概括可以克服/克服上述困难吗?

2 个答案:

答案 0 :(得分:5)

您链接到的维基百科文章有一个关于handling these special positions的部分,它建议对基本算法进行这些修改:

  • 按照惯例,一点是垂直在其上方的点的“左”;因此,垂直线的“左”端点是 lower 端点。
  • 事件可能包含两个或更多行的交叉。
  • 当达到事件点时,其事件段必须在扫描行中反转(不仅仅是交换,因为可能有两个以上)。
  • 处理完交叉后,可能会删除两个以上的旧事件点,或者多个要插入的新事件点。

答案 1 :(得分:5)

这些是对Skanthak here:提出的算法的修改。

  

算法如下:它首先为输入段的所有起点和终点创建事件。    然后它按排序顺序处理所有事件   对于每个事件,它都会获取    从该点开始的段的关联列表 L    并找到并删除搜索树中的所有段    与当前事件点相交的。   它将所有这些段报告为该点的交叉点。   然后它切换比较功能的顺序    通过在当前事件之后稍微改变fl ag。   它重新插入以前删除的所有段    没有在当前事件点的端点    (因为他们必须被删除     从这个结构来看反正)    另外插入来自 L 的片段    (从这一点开始)。   它检查顶部和底部邻居    在新交叉点的当前事件点之上和之下    如果发现任何事件,则将它们添加为事件点   这种算法是健壮的    反对各种退化,    包括垂直段和重叠段,    以及在其端点上相交的段。

for all segments s do
  Create events for the endpoints of s
end for
while event queue not empty do
  Remove the smallest event point p from the queue
  Let L be the set of segments that start at p
  I ← all segments in the sweep line structure that contain p
  remove I from sweep line structure
  if |L| + |I| ≥ 2 then
     Report intersections of L ∪ I
  end if
  C ← {s ∈ I | p is not endpoint of s}
  Insert C in sweep line structure in reversed order
  Check for new intersections among segments above and below p
end while