最近我偶然发现Twitch.TV上的频道来自执行经典游戏速度的玩家。其中一人玩The Legend of Zelda - A Link to the Past。我看到许多低效的动作,我开始怀疑 - 鉴于世界地图数据 - 是否有可能编写一个执行完美速度的机器人。一个经常出现的子问题是找到一个平面中两点之间的最短路径,我认为这是一个非常有趣的问题,我开始对此进行更多的研究。
Finding path obstacles in a 2D image
Algorithm to detect corners of paper sheet in photo
......还有更多
其中答案总是为Superproblem(如下所述)提供不同的解决方案,例如使用基于网格的方法,但不是我感兴趣的实际子问题(如下所述)。
在平面中给出两个点X=(x1,x2)
和Y=(y1,y2)
- 如果平面包含路径可能通过的障碍物/区域,则从X
到Y
的最短路径是什么?不是领导?
不同/更直观从Link的当前位置到地图上的第二个红点的最短路径是什么?因为他无法爬过墙壁或穿过灌木丛?
此问题通常称为Eucledian Shortest Path Problem,可以在二维情况下在Polynomial time中解决。真棒!
为实现这一目标,构建了一个带V= {X,Y} U {"Corner-Points of obstacles}"
的所谓Visibility Graph。当且仅当可以从P and Q
到P
绘制直线而不跨越任何障碍时,将在Q
点之间插入边。每条边都由它连接的点之间的Eucledian Distance加权。
在上面的示例中,可见性图表看起来像这样。为了便于阅读,我省略了一些边缘和重量。阴影区域说明了障碍。
然后可以使用开发人员在可见性图上最喜欢的最短路径算法计算最短路径。
让我们首先将障碍定义为不可通行地形的连续区域。如何找到所有障碍物的最小数量的所需角(以及角的坐标)来构建执行最短路径计算所需的最小可能性图?
对于矩形障碍物,很容易找到角落,因为草图中只显示了很少的尖锐边缘...
...或应用于游戏中的场景
然而,一旦障碍物具有对角线“前线”,由于诱导的拼图模式(无论角度),获得角落变得非常重要。以下屏幕截图说明了这个问题:左侧图像显示哪个坐标点应该被识别为角点,而右侧图片显示由于“竖锯” - 对角线图案而插入附加点的位置。
现在的问题是:如何从可能非常大的可见性图中排除/阻止这些不必要的角点?
答案 0 :(得分:2)
如何查看每个点周围的点,如果您发现两个点完全相反但没有穿过“实心”,那么您就知道实际上有一个删除候选者。在删除之前对所有点执行此操作,然后一次性删除所有这些候选项。
这将处理水平,垂直和对角线。如果将半径扩展到两个或更多,则还可以检测其他角度的“线”上的冗余点。
时间复杂度几乎是O(n)(当n是点数时),因为你将检查每个点周围的固定数量的点以找到删除候选者,例如:
半径1 - 4个相邻点对,每点检查:
123
4X5
678
=>检查对(1 8),(2 7),(3 6),(4 5)
半径2 - 8个相邻点对,每点检查:
1 2
34567
8X9
ABCDE
F G
=>检查对(1 G),(2 F),(3 E),(4 D),(5 C),(6 B),(7 A),(8 9)