【问题标题】:O(nlogn) divide and conquer algorithm to find visible linesO(nlogn) 分治算法找到可见线
【发布时间】:2016-01-05 12:14:54
【问题描述】:

我正在尝试解决附图中显示的问题。我得到了分割部分,您可以在其中递归地将线集分成两半,并且可以看到具有最小和最大斜率的线。

我不知道如何做合并部分,我不明白。

直觉上,起初,我认为如果没有三条线在一点相交,所有线最终都会可见。

同样,征服部分是我会取出看不见的线条......据我了解,在征服阶段之前不应该有任何线条被取出。

如果有人可以为我们这些大脑有点慢的人解释一下,我将非常感激! :)

【问题讨论】:

  • 如果没有说明性图像,我们只能猜测......计算机 gfx 中看不见的线条去除通常是通过计算表面法线(如果网格是凸面的)来完成的。在此之前,凹面网格细分为凸面网格。可能还有其他算法利用已知的情况来使用它,但如果没有更多信息,很难说你的例子指的是什么。如果您的网格是实心的(不仅仅是线框),那么您可以使用 Z 排序或 Z 缓冲,但我想这不是您想听到的

标签: algorithm divide-and-conquer


【解决方案1】:

考虑一个 3 行示例。您有 2 个选项。 a) 只有 2 行可见 b) 所有 3 行都可见。

因此您需要确定中间的是否可见。为此,您可以计算外部 2 条线的交点(称为 A)。如果A在中间线上方则中间那条是隐藏的,如果在下方则可见(画两个图就很明显了)。

要确定该点是高于还是低于线方程中的坐标 (y = ax + b)。如果y > ax + b 则该点在线上,如果y < ax + b 该点在下方,如果y = ax + b 该点在线上(根据问题不应该发生)。

为了解决您的问题,我将按照斜率的顺序排列线条并尝试将它们添加到解决方案中。每次添加新行时,请检查前一行是否仍然可见,如果不可见则将其删除(根据需要重复多次,因为新行可能会隐藏不止一个前一行)。

如果您坚持要进行合并,则需要在合并行上应用此逻辑,以确定您从中间删除了多少行。

【讨论】:

  • 如果我没记错的话,这将需要 O(n^2) 运行时间。我们可以在 nlgn 中做吗?
  • 它是 NlogN 因为排序。添加和删​​除是 O(N),因为您只添加了一次,然后可能稍后您将其删除(但只有一次)。
  • 每次添加新行并尝试检查它是否可见时,都会与所有其他行一起检查它,这将花费 O(n) 时间。因此,整个算法将花费 O(n^2),因为您正在为所有 n 行执行此操作。
  • @MoGanji 你只是部分正确。一行可以检查所有其他行并导致 O(N),但是这不可能发生在每一行。一种思考方式是,每行添加一次 O(1)。对于每一行,您都有一堆检查失败并删除一行(可能是 O(N) )和一个通过并停止迭代 O(1) 的检查。所以现在总结一下,我们添加 O(N) 行,我们有 O(N) 检查通过和停止迭代,我们将有 O(N^2) 行删除。但是最后一个不能发生,因为您只能删除 O(N) 行,因为我们总共只有 N
  • @Sorin 这是一个很好的解释,但是,您如何确定在每次迭代中都删除了一行?如果迭代最终没有删除行怎么办?在这种情况下,可能有 O(n^2),对吧?
猜你喜欢
  • 1970-01-01
  • 2015-07-07
  • 2016-02-11
  • 2013-02-03
  • 2013-12-06
  • 2011-11-17
  • 2017-08-19
  • 2020-10-03
相关资源
最近更新 更多