7

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), first-order diagonal (0,1,1) and second-order (1,1,1).

What I'm mostly concerned about is the optimal turning points defined in the paper. I've been unable to ascertain exactly how they were derived, and therefore how to derive my own for three dimensions.

Any suggestions as to how this can be done?

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 1
    My read of the paper was that the jump points were the optimal turning points and that algorithm 3 was there, "merely as a conceptual device" to prove that using these jump points had "no effect on the optimality of search." – user7116 Apr 19 '12 at 14:59
  • So you think they just arise out of the algorithm, rather than something you have to explicitly program in? – Puppy Apr 19 '12 at 15:11
  • They lay the paper out in three parts, the first of which describes their pruning strategy and how you add nodes (i.e. the *jumping* along a given direction `d`). The second part, which brings up turning-points, they state is merely a "theoretical result which shows that searching with jump points preserves optimality". The last part was simply a benchmark and does not use Algorithm 3 (the path reduction using turning points). – user7116 Apr 19 '12 at 15:14
  • There is an assumption in the 2D JPS algorithm. The lemma is that you can't ever get trapped in a "looping" expansion, since expansion is diagonal first and all secondary h/v's are dependent on the chosen direction. Ergo, you can't end up in the same place. I can't prove nor disprove this, but in 3D it seems less obvious whether that lemma holds or not by merely extending the 2D case into 3D. – StarShine Nov 05 '14 at 20:41
  • The turning points are only used for the proof that the algorithm finds an optimal path? Just focus on the jump points and correct pruning forced neighbours instead maybe. – soncis Jun 10 '16 at 07:06

1 Answers1

4

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]
Aaron3468
  • 1,734
  • 16
  • 29
  • Im trying this out, the forced neighbor situation is pretty.. wierd. I have a difficult time wrapping my head around it. You cannot implement the 2D forced neighbor x3 in 3D either that will become wrong. If someone got an example for which nodes can be pruned and which have to be checked for forced neighbors in 3D case please inform :p – soncis May 30 '16 at 11:35
  • 1
    ok I managed to figure out all the forced neighbor cases for 3D JPS so if anyone needs help, contact me ^^ – soncis Jun 09 '16 at 12:45
  • Do note that [1, 1, 1] is directly toward the target, and you'd need to rotate the whole set of points to turn them into your global coordinate system. There'd be 8 times the list if I did not use relative coordinates – Aaron3468 Jun 09 '16 at 16:53
  • @soncis If I could get any more information about your solution, I would be greatly appreciative! – Enqueuing Sep 08 '16 at 19:36
  • ofc! what you need? :) my 3D JPS works well in my program and runs usually ~10 times faster than A*. It dont need heuristics either but there is.. alot of code you will have to be specific. – soncis Sep 12 '16 at 11:45
  • @soncis Would you possibly be willing to contact me via email? gabriel @ zanmgt.com. I have quite a few questions! – Enqueuing Sep 26 '16 at 15:03
  • I want to implement A* and JPS in a voxel game similar to Minecraft. I have a basic A* algorithm that works fine in a flat map. But implementing the 3rd dimension kills my brain. I need to implement the possibility that entities can jump over nodes, but to find the right path I also have to check the clearance above the head. Another issue is that entities can have different sizes, which makes it more complicated. Has someone an idea how I can implement this? – burli Apr 10 '17 at 11:42