不幸的是,我对扫描线算法的理解还不是很强。关于该主题的所有论文和教科书均已阅读,但理解距离还很远。为了更清楚一点,我尝试解决尽可能多的练习。但是,真正有趣和重要的任务仍然对我构成挑战。
我在万能杰夫·埃里克森(Jeff Erickson)的《线段相交》的讲义中发现了以下练习。
练习2。描述并分析扫掠线算法,以在给定平面中的圆的情况下确定在时间内是否有两个相交。每个圆都由其中心和半径指定,因此输入由三个数组和。注意正确实现低级原语。
让我们尝试使复杂的事情变得容易。我们对圆的交点了解多少?用线的交点可以找到什么类似物。如果两条线相邻,两条线可能会相交,两条圆应该具有哪个属性才能相交?令为圆心,和圆心之间的距离。考虑几种情况:
情况1:如果,则没有解,圆是分开的。
情况2:如果那么就没有解决方案,因为一个圆包含在另一个圆内。
情况3:如果且则圆是重合的,并且解的数量是无限的。
因此,看起来交叉路口的条件已经准备就绪,当然可能是错误的条件。如果是这样,请更正。
算法。现在我们需要找到两个相交的圆之间的共同点。在模拟到直线相交的情况下,我们需要在事件队列中具有插入条件和删除条件。假设事件点是垂直扫描线接触的第一个点和最后一个点的x坐标。在第一个点上,我们将圆插入状态, 并检查与最近的圆的交点(上面提到了3种检查情况),在最后一点上,我们从status中删除了圆。
对于扫掠线算法来说似乎已经足够。如果有什么问题,或者可能有什么事情应该做不同的事情,请随时与我们分享您的想法。
附录:
我在垂直扫掠线第一次接触该圆时插入一个圆,并在扫掠线最后接触该状态时从状态中删除一个圆。交叉点的检查应在最近的前一个圆上进行。如果我们在状态中添加了一个圆圈,并且之前已经添加了另一个圆圈,并且该圆圈仍然存在,那么先前的圆圈不会“闭合”,因此可能存在相交。
status
保持当前与扫描线相交的圆?假设您当前有100个圆圈status
,并且您要处理一个插入事件并插入第101个圆圈。您比较多少个圆来检查路口?您如何选择要比较的圈子?