pyastar2d icon indicating copy to clipboard operation
pyastar2d copied to clipboard

Path is not straightforward when allow_diagonal is set to True, and to extract additional information from the pathfinding object.

Open rllyryan opened this issue 3 years ago • 1 comments

Dear @hjweide

This is the result when allow_diagonal is set to True, and the output shown below is not desired from the program. image

This is the result when allow_diagonal is set to False, and the output shown below is what was desired from the program. image

I also noticed that the path infiltrates the walls for some unknown reasons.

Update: It does not seem like an infiltration but it seems to 'glow' around the path. image

The presence of imperfect grayscale pixels were taken into account for in the code below:

maze = img.astype(np.float32)
maze[img < 240] = np.inf
maze[img >= 240] = 1.0

Could I ask you for your recommendation as to how I should go about optimising this? Could it be that diagonal movements are less costly than straight movements?

On the other hand, I would also like to ask if I am able to extract the path cost (this takes into account diagonal movements that cost sqrt(2))? If not, could you recommend how I should go about modifying the package contents? (refer to code snippet below)

for i in range(len(self.PATH)-1): #calculates the cost of the path
            cur = self.PATH[i] 
            nxt = self.PATH[i+1] 
            
            if (cur.x_pos == nxt.x_pos and cur.y_pos != nxt.y_pos): #if vertical movement
                self.COST+=1
            
            elif (cur.x_pos != nxt.x_pos and cur.y_pos == nxt.y_pos): #if horizontal movement
                self.COST+=1
            
            elif (cur.x_pos != nxt.x_pos and cur.y_pos != nxt.y_pos): #if diagonal movement
                self.COST += math.sqrt(2) 

rllyryan avatar Aug 01 '22 03:08 rllyryan

This is the result when allow_diagonal is set to True, and the output shown below is not desired from the program.

This is because you have a uniform grid and so there are many shortest paths that are all optimal even if they don't "look right". The A* algorithm simply picks whichever it discovers first, which is determined by the order in which the heuristic function adds nodes to the priority queue. The cost of the path is the nodes included in that path; the direction of movement is irrelevant. If you want straight paths you either need to disable diagonal moves or use a heuristic that breaks ties to get the types of paths you want. See some of the discussion and the changes from here: https://github.com/hjweide/pyastar2d/pull/29

Also note that A* is not really meant for uniform grids and so most ways of getting A* to produce straight paths will involve hacks. See this blog post for a great discussion on this topic: https://www.redblobgames.com/pathfinding/a-star/implementation.html#troubleshooting-ugly-path

Update: It does not seem like an infiltration but it seems to 'glow' around the path.

This is just a problem with the plotting or how you are saving / viewing the image. Be sure to plot as uint8, use (0, 0, 0) and (255, 255, 255) for black and white, and use a lossless format like PNG with a viewer that does not smooth.

I am able to extract the path cost

The easiest way to get the cost of the path would be something like this:

cost = np.sum(grid[path[:, 0], path[:, 1]])

Note that the direction of movement does not affect the cost of the path.

hjweide avatar Aug 02 '22 01:08 hjweide