3D search using A* JPS

前端 未结 1 530
逝去的感伤
逝去的感伤 2021-02-09 10:22

How can I generalize Jump Point Search to a 3D search volume?

So far, I have defined pruning rules for a 3D cube involving each of the three movements- straight (0,0,1),

1条回答
  •  悲&欢浪女
    2021-02-09 11:08

    Rather than attempting to derive turning points, it helps to use an intuitive understanding of the algorithm in 2D.

    Because the shortest distance between two locations is a straight line, we know that moving diagonally is fastest because it's equivalent to two steps in 1D. In 3D, this means a diagonal is equivalent to three steps. (in reality, these values are sqrt(2) and sqrt(3)). With this, we choose to optimize by moving across as many axis as possible... Turning to move along a 2D axis is worse than turning to move along a 3D axis. Likewise, moving along 1D (straight) is even worse than 2D movement. This is the core assumption jump-point makes.

    There is, in the culling algorithm, the assumption that if you are jumping on the least optimal axis (1D), then there are no optimal turns of a higher axis order (turning onto a 2D axis) until there is a parallel wall on the same axis order. For example, look at figure 2(d), where the code sees a parallel wall in 1D and adds a 2D movement back into the list.

    As a Heuristic

    Evaluate forward until one space is left open (and a wall is 2 spaces away), and add this point to the jumplist. For any point on the jumplist, jump in a new direction. goal > 2D movements forward > 1D movements forward > 1D movements backward > 2D movements backward. We can generalize this heuristic to any n dimension...

    Evaluating the next direction, with + being towards the goal, and n being the amount of dimensions incremented gives us the equation... +nD > +n-1 D > ... +1D > 0D > -1D > ... > -n-1 D > -nD

    The order of best->worst turning points in 3D

    1. 3D+ = [1, 1, 1]
    2. 2D+ = [1, 1, 0], [1, 0, 1], [0, 1, 1]
    3. 1D+ = [1, 0, 0], [0, 1, 0], [0, 0, 1], [-1, 1, 1], [1, -1, 1], [1, 1, -1]

    (suboptimals below; [0, 0, 0] is useless, so I didn't include it)

    1. 0D = [1, -1, 0], [1, 0, -1], [-1, 1, 0], [-1, 0, 1], [0, -1, 1], [0, 1, -1]
    2. 1D- = [-1, 0, 0], [0, -1, 0], [0, 0, -1], [-1, -1, 1], [1, -1, -1], [-1, 1, -1]
    3. 2D- = [-1, -1, 0], [-1, 0, -1], [0, -1, -1]
    4. 3D- = [-1, -1, -1]

    phew typing that was a pain, but it should solve your problem.

    Just remember that as you 'jump', keep track of which order of axis you are jumping; you need to find parallel walls in the same axis. Therefore, moving in the direction [1, 0, 1], you want to find walls that are at [1, 1, 0] and [0, 1, 1] in order to 'unlock' a jump point in the direction [1, 1, 1].

    With the same logic, if you move in 1D [1, 0, 0], you check [0, 1, 0] for a wall to add [0, 1, 1] and [1, 1, 0]. You also check [0, 0, 1] in order to add [1, 0, 1] and [0, 1, 1] as jump points.

    Hopefully you get what I mean, because it's really difficult to visualize and calculate, but easy to grasp once you have the mathematics of it.

    Conclusion

    Use the A* heuristics...

    • Dijkstra = distance from start
    • Greedy First = distance from goal

    Then add our new heuristics!

    • +nD > +n-1 D > ... +1D > -1D > ... > -n-1 D > -nD
    • if any point nD has a parallel obstruction, you may add a jump point for each open n+1 D direction.

    EDIT: The definition of 'parallel' for your code

    • any point that is the same order as the direction you are moving
    • not the next point in that direction
    • has the same amount of positive and negative dimensional moves as the next point (e.g, [1, 1, -1] is parallel to [1, -1, 1] and [-1, 1, 1], but not to [1, 0, 0]

    0 讨论(0)
提交回复
热议问题