Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Work in Progress / A* Nodes

Author
Message
Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 7th Sep 2008 01:33 Edited at: 7th Sep 2008 15:00
A* Nodes


As you can probably guess from the name, A* Nodes is a path-finding plugin which uses nodes instead of the normal grid.

Also, the plugin is capable of both synchronous and asynchronous path-finding. (synchronous version doesn't return from the function until it is done, asynchronous sets it going in a separate thread, and will return immediately)

Done:
2d Path-finding (used for 2d and 3d top-down path-finding)
manual addition of nodes
automatic addition of nodes by adding shapes
radius
asynchronous and synchronous path-finding (there's no pause when trying to calculate a very long path)
Up to 31 asynchronous and 1 synchronous searches running at the same time!
Fixed problem with over-guessing remaining distance (meant it didn't find the shortest path!)
built in circle casting
remove dependencies on other plugins

Will do:
3d equivalent (nodes have a Z location)
find slow code and OPTIMIZE!
add some debug drawing commands (eg. draw node positions and shapes)



Example:


-- UPDATED 07 SEPTEMBER --
Plugin download: HERE

Command list:


To install:
- Place the .dll in your compilerplugins-user folder
- Place the .ini in your editorkeywords folder

Instructions:
1) create a world using asCreateWorld2d <id>,0
2) add shapes to the world using asAddWorldShape <worldid>,clockwise vertex list...
3) calculate the nodes using asCalculateWorldNodes <worldid>,<radius>
4) use asFindPath2d to find a path from one point to another
(see example for how to do it asynchronously)

Enjoy


____________________________________

How it works

The plugin is split into two parts:
1) The automatic node maker
The automatic node maker takes a series of polygons (stored as a list of clockwise ordered points) and outputs the nodes necessary to get around the shapes.
- Nodes must be at least <radius> distance from every shape
- Nodes only need to be present on outward pointing vertices.
- Nodes cannot be inside a shape
To accomplish this, the plugin moves the border of every shape out by <radius> units, and then again for another 1/100th of the radius.
All the vertices in the second set of polygons generated are checked to see if they are inside any of the polygons generated by the first enlargement.
If they are not in any of them, and they 'stick out' (the angle < 180 degrees) they are added to a single final polygon, which just holds the list of nodes.
All these nodes are added to the world.
Every node in the world is checked with every other node in the world, to see if the can see each other, using either a user function, or a built in one.
In the built in one, the enlarged shape list is used for the ray casting to effectively do a circle cast instead of a ray cast.
If two nodes can see each other a path is created between them.

Algorithms used:
- 2d cross product to move a line outwards
(just change the y to 0-the old x, and x to the old y, then divide by the length to normalise it)

- Line intersection
for each line x1,y1,x2,y2:
A = y2-y1
B = x1-x2
C = A*x1+B*y1

A1/B1/C1 is the A/B/C for line 1
A2/B2/C2 is the A/B/C for line 2
x/y is the final intersection point

det = A1*B2 - A2*B1
if det = 0
-> Lines are parallel
else
-> x = (B2*C1 - B1*C2)/det
-> y = (A1*C2 - A2*C1)/det



2) The path-finder
The path-finder uses the A* path-finding algorithm, which works like so:
Each node has an F,G,H and P value.
G is the total distance to get to the node.
H is the estimated distance to the finish
F is G+H
P points to the node which comes before this node in the path (to follow it back after)
There are two lists of nodes, an 'open' list and a 'closed' list. First of all, the starting node is added to the open list.
Then the loop begins:
1. The node in the open list with the smallest F value is selected.
2. If there are no more nodes in the open list, there is no path from start to finish
3. This node is moved to the closed list.
4. If this node is the finish node, the path is found, exit the loop and just go back up the path by following the P values
5. All the nodes connected to this node are looped through
6. If the node is in the closed list, ignore it
7. If the node is in the open list, and the G value of the selected node plus the distance to the node is less that its current G value
8. Then change the G to the new G value, and change P to point to the selected node
9. Otherwise, ignore it
10. If it's in neither list, add it to the open list
11. The G value is the G value of the selected node, plus the distance from the selected node to this new node
12. The H value is the distance in a straight line from the node to the finish
13. Set P to point back to the selected node
14. Loop back to 1

An explanation for the grid method (which is the same but using cells instead of nodes) can be found here: http://www.policyalmanac.org/games/aStarTutorial.htm

I hope some people learn from this!

[b]Yuor signutare was aresed by a deslyxic mud...
BOX2D V2 HAS HELP FILES! AND A WIKI!

Attachments

Login to view attachments
Phosphoer
16
Years of Service
User Offline
Joined: 8th Dec 2007
Location: Seattle
Posted: 7th Sep 2008 07:43
This sounds quite cool, nice work! If I need any pathfinding AI ever I'll definitely give this a look

Sven B
19
Years of Service
User Offline
Joined: 5th Jan 2005
Location: Belgium
Posted: 7th Sep 2008 13:29
Could you also give some performance results?
This looks pretty neat!

It's the programmer's life:
Have a problem, solve the problem, and have a new problem to solve.
Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 7th Sep 2008 13:56 Edited at: 7th Sep 2008 14:54
Thanks, I've just finished a built in test to see if nodes can see each other, and it's faster than using sparky's instead.

When logging how long it took each piece of code to execute I accidentally made a 3.5gb log file, with 500 cubes
That means that it has to do about 600 million line intersection tests during setup! (and without logging, it takes only a few seconds, so I think that part is reasonably well optimized...)

edit:
Just updated!

[b]Yuor signutare was aresed by a deslyxic mud...
BOX2D V2 HAS HELP FILES! AND A WIKI!
RedFlames
17
Years of Service
User Offline
Joined: 25th Aug 2007
Location: Germania
Posted: 7th Sep 2008 19:00 Edited at: 7th Sep 2008 19:00
I just tested it and it took long to generate the path and i tracked it down to this part:

it takes about 10 seconds for me... (which is pretty long if you consider that the screen stays black for 10s) and im wondering... is this normal?

otherwise nice plugin, maybe ill use it... (although i got DarkAI )

Diggsey
18
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 8th Sep 2008 01:55
I don't think that's right, for me it's the 'asCalculateWorldNodes' command that takes a while. I'll check though...

[b]Yuor signutare was aresed by a deslyxic mud...
BOX2D V2 HAS HELP FILES! AND A WIKI!

Login to post a reply

Server time is: 2024-11-24 08:12:31
Your offset time is: 2024-11-24 08:12:31