2D waypoint pathfinding: combinations of WPs to go from curLocation to targetLocation
Please take a moment to understand my situation. If it is not comprehendable, please tell me in a comment.
I have an ArrayList of Waypoints. These waypoints are not in any order. A waypoint has the following properties:
{int type, float z, float y, float x, float rotation}
This applies to a 3 dimensional world, but since my pathfinding should not care about height (and thus treat the world as a 2 dimensional one), the y value is ignore开发者_运维技巧d. Rotation is not of importance for this question.
- In this 2 dimensional world, the x represents the x axis and the z represents the y axis.
- If x increases, the object in the world moves east. If x decreases, the object in the world moves west.
- If z increases, the object in the world moves north. If z decreases, the object in the world moves south.
Thus, these "new" waypoints can be simplified to: waypoint = {float x, float y}
.
Now, these waypoints represent the X-axis (x) and Y-axis (z) locations of an object. Moreover, there is a current location: curLocation = {float x, float y}
and a target location: tarLocation = {float x, float y}
.
This is what I want to get:
All combinations of waypoints (aka: paths or routes) that will lead fromcurLocation
to tarLocation
under the following strict conditions:
- The distance inbetween each waypoint may not be bigger than
(float) maxInbetweenDistance
. This includes the initial distance fromcurLocation
to the first waypoint and the distance from the last waypoint totarLocation
. If no such combination of waypoints is possible, null should be returned. - When multiple waypoints are found within
maxInbetweenDistance
from a waypoint that lead towards the target waypoint, the closest waypoint should be chosen (even better would be if an alternative waypoint that is slightly further away would result in a new path with a longer distance that is also returned). - The order of returned waypoint combinations (paths) should be from shortest route (minimum distance) to longest route (maximum distance)
Finally, please consider these points:
- This is the only thing I need to do AI/pathfinding wise, which is why I do not wish to use a full blown pathfinding or AI framework. I believe one function should be able to handle the above.
- If returning all possible combinations of waypoints causes too much overhead, it'd also be fine if one can specify a maximum amount of combinations (but still ordered from closest to furthest). Eg. the 5 closest paths.
How would I achieve this? Any feedback is appreciated.
I think your solution is to start with Dijkstra's Algorithm to find the shortest path first. You can consider your waypoints to be a connected graph where nodes are connected if they are close enough in the xy plane then apply Dijkstra (there are many example code listings online).
Now you have the shortest path through your graph from start to finish, which will be composed of N edges of the graph.
You would next need to create N new graphs, each just like the first, but with one segment of your shortest route un-connected. Find the shortest routes from start to finish on these modified graphs. Now you have N+1 routes which you can sort by length.
Repeat this until you have found enough paths for your needs, or there are no unranked paths left.
I haven't found a name for this technique, but it is described as a modification to Dijkstra here.
If your waypoints possess connectivity, you should take a look at Dijkstra's shortest path algorithm. The first couple of google hits even lists an implementation in Java. (I can't tell if connectivity is known from the post, but it does contain the "graph-algorithm" tag, so I'll assume so). As the name suggests, this method give you a shortest path between the two nodes.
Your constraints are challenging, as is the need for all possible combinations of paths under those constraints. Again - assuming connectivity exists - your node adjacency matrix can enforce your maxInbetweenDistance rule. Likewise, you can use this matrix in obtaining the "next best" solutions. Once the optimal path is known, you can mark that path (or elements of it) as unavailable, then re-run Dijkstra's algorithm. By repeating this process, you can obtain a set of increasingly sub-optimal paths.
As a matter of convention: in most computational geometry problems, Z is the height, and the horizontal plane is formed by the XY axes.
Well the easiest to implement would probably be creating an ArrayList of paths, which would be in turn an ArrayList of waypoints, that contains ALL possible paths, then using a recursive function to return whether each path is Valid or not given the starting and finishing point values, and the max distance, and if a path is not valid remove it from the list. The next step would be going through each of the paths that is left and ordering them from shortest total distance to shortest. This would be the brute force method of getting what you want, so the least efficient one possible. When I get home tonight I will repost if some one already hasn't with a more efficient method for doing this in java.
Edit: if the brute force method is too much, the list of waypoints will have to be sorted some how, the best way is probably to sort them initially based on distance from the starting point.
精彩评论