检查直角形的有效性

4
给定一个直角形状,如何有效地检查它是否有效并指出无效的部分?
这里的有效性意味着宽度约束,即形状的每个部分的宽度都不应少于某个值d。形式上,如果您从形状的顶部向底部垂直扫描一条线,则线与形状之间的所有交点的长度都不应小于d。垂直情况类似。
(请注意,形状内部可能会有孔。但为简单起见,我们可以先忽略它。)
有人能提出一个有效的算法或向我展示一些指向此问题的指针吗?

1
如果你有一个洞,它的宽度是否包括这个洞?比如说你有一个 O 形。在中间位置,它的宽度是 2 还是 3(假设洞和所有边都是长度为 1)? - corsiKa
2个回答

1

我认为你可以采用一种相当典型的扫描线方法来解决这个问题。

首先考虑水平扫描线,从图形顶部向底部扫描。注意,扫描线所跨越的宽度只能在它穿过垂直线段的端点时发生变化。

因此,在水平扫描线中,您可以忽略水平线段。将所有垂直线段的端点按其垂直位置排序。(每个端点都知道它是其线段的“顶部”端点还是“底部”端点)。

按顺序处理排序后的列表以模拟扫描线。维护一个初始化为空的“活动集”S。当您遇到“顶部”端点时,将其线段添加到S中。当您遇到“底部”端点时,从S中删除其线段。验证活动集的宽度始终满足您的约束条件,然后您就完成了。

使用平衡二叉树(如C++的std::set)来表示活动集,使用水平位置作为比较函数。这样可以O(1)检索集合中最左和最右的线段,因此宽度计算是O(1)。它还允许O(log n)的插入和删除,由于每个垂直线段只插入和删除一次,因此整个扫描需要O(n log n)。

对于垂直扫描线,重复对称操作。

每个排序都是O(n log n),每个扫描都是O(n log n),每个方向乘以2...因此总体算法是O(n log n)。


0

这里有一种大力法,时间复杂度约为O(n^2)。

首先检查是否存在任何自交。多边形中的交叉点宽度为0,因此会自动失败。

解决方案的其余部分分为两个部分,具体取决于您的限制是仅水平和垂直还是任意角度。对于任何情况,都从迭代多边形的每个点开始。

如果限制是水平/垂直的,请检查多边形的每个线段,以查看它是否与通过该点的x或y的线相交。如果相交,则计算交点到该点的距离;如果小于限制,则失败。

如果限制是任意角度,请检查不相邻于该点的多边形的每个线段,并计算线段到该点的最短距离;您可以从这个问题点和线段之间的最短距离中得到一些帮助。如果距离小于限制,则失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接