【问题标题】:Check if a Circle fits through a maze in non-quantized 2d space检查圆形是否适合非量化二维空间中的迷宫
【发布时间】:2020-07-26 15:47:16
【问题描述】:

我是一名高中生,最近参加了一个编程比赛,遇到了一个我不知道如何解决的问题:

给定一个封闭在 100x100 区域中的迷宫,根据所有墙壁的位置确定具有给定半径的圆是否可以穿过迷宫。墙将被定义为连接空间内两个点的线,您将获得圆的起点和终点。圆圈必须以起点为中心并接触目标点才能成功穿过迷宫。最多有 20 面墙。圆的半径和墙壁的位置可以“任意”精确。 (在这种情况下,“任意”仅表示在很远的范围内 - 比如说,最多小数点后 10 位)。

这是一个例子。如果这是输入:

Radius = 2.8
Start = (5,5), Destination = (95,95)
Walls (a wall connects each pair of points):
(20,0) to (27.5,22.6)
(27.5,22.6) to (55.1,35.5)
(55.1,35.5) to (80.3,80,4)
(80.3,80,4) to (95,63.9)
(1.7,25.8) to (17.5,53.2)
(17.5,53.2) to (56.4,69)
(56.4,69) to (67.9,90.6)
(85.6,98.94512) to (87.3,92.5)

那么这个(在desmos上制作)就是迷宫的样子(蓝色圆圈只是为了显示圆圈有多大):

如果问题在量化网格中,我会知道如何解决问题,但墙壁的确切位置和圆的半径可以任意精确。我曾想过使用“右手法则”来寻找路径,但我不知道如何在非量化空间中实现(我对方法也不是很熟悉)。

我将如何解决这个问题?有人可以给我指出一个算法、一个链接、一些伪代码,或者只是一种直觉,可以帮助我理解如何解决这个问题吗?任何帮助表示赞赏。谢谢!

【问题讨论】:

    标签: algorithm search 2d maze


    【解决方案1】:

    r 在每一侧加厚/移动墙壁,就像在另一个答案(+1 btw)中一样,听起来很简单,但编写代码并不是一件容易的事。有关详细信息,请参阅

    如果dx,dy 是线方向,那么二维中的法线方向很容易,那么(-dy,dx)(dy,-dx) 是它的法线方向...

    但是我鼓励通过计算迷宫的每个顶点到墙壁的最近距离以及比2r更近的路径来做更慢但更安全和更容易的方法...

    类似这样的:

    所以:

    1. 每个顶点
    2. 检查所有不属于顶点路径的行
    3. 计算d 到直线及其顶点的垂直距离和最小距离 使用最小的d 距离可以很容易地计算出来看看:

      在那里寻找Perpendicular distance of any point P to AB 所以:

      d = min
            (
            perpendicular_distance(line,vertex), 
            |line_vertex1-vertex|, 
            |line_vertex2-vertex| 
            )
      

      如果d<2r 关闭路径。例如,通过添加一条连接墙的线太靠近测试的顶点

      理想情况下,通过连接测试顶点和找到的最近点。在这种情况下,不要忘记将相对的墙线按最近的点一分为二,这样您的图形算法仍然可以工作......

    如您所见,这是O(n^2),而不是其他答案中的O(n),但它的防犯规......扩大多边形不是,事实上它是二维几何中最难编码的事情之一( IIRC 甚至还有待解决的问题)...

    【讨论】:

      【解决方案2】:

      这是一项艰巨的任务并且不容易编码,但这里有一种可行的方法:

      r 为圆的半径。这意味着圆的中心不能进入任何障碍物的r范围内。

      将迷宫区域的墙壁每边移动 r

      用半径为 r 的圆替换每个墙端点。

      用宽度为 2r 的矩形替换每面墙。

      现在您无需担心圆 - 只需关注它的中心点,它必须保持在新边界内,并且在您从墙壁上制作的任何圆或矩形之外。

      现在,如果它们在同一个封闭区域中,则有一条从起点到终点的路径。要找出答案...

      在每个交叉点和垂直最大值或最小值处水平切割场景以创建条带,每个条带由一条一直穿过它的直线或圆弧划分为多个区域。一个区域不会将方向连接到它的左右区域,但可以连接到它上面和下面的条带中的零个或多个区域。区域之间的联系形成了一个图表。

      从包含起点的区域开始,在此图上运行 BFS 或 DFS,看看是否可以到达包含终点的区域。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-02
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多