@@ -52,6 +52,10 @@ namespace alg {
5252
5353 private:
5454 const Array2D<unsigned char > & m_grid;
55+ // the openset
56+ Heap<uint32_t > m_openset;
57+ // The set of nodes open -- for fast testing of a point in openset. heap contains test is quite slow -- O(n)
58+ Array2D<bool > m_openset_grid;
5559 // The set of nodes already evaluated.
5660 Array2D<bool > m_closedset;
5761 // Cost from start along best known path.
@@ -61,9 +65,14 @@ namespace alg {
6165 public:
6266 AStar (const Array2D<unsigned char > & grid) :
6367 m_grid (grid),
68+ m_openset (grid.row()*grid.col()),
69+ m_openset_grid (grid.row(),grid.col()),
6470 m_closedset (grid.row(),grid.col()),
6571 g_score (grid.row(),grid.col()),
66- f_score (grid.row(),grid.col()) { }
72+ f_score (grid.row(),grid.col()) {
73+ m_openset_grid.clear (false );
74+ m_closedset.clear (false );
75+ }
6776
6877 /* *
6978 * the A* algorithm
@@ -74,32 +83,38 @@ namespace alg {
7483 static float SQRT2 = 1.414213562373095 ;
7584 uint32_t nrow = m_grid.row ();
7685 uint32_t ncol = m_grid.col ();
77- m_closedset.clear (false );
86+
87+ // test wheather the (x1, y1) is the wall, we don't do stupid searching.
88+ if (m_grid (x1, y1) == WALL) {
89+ return NULL ;
90+ }
7891
7992 // the set of tentavie nodes to be evaluated,
8093 // initialy containing the start node
8194 // encoding [x,y] to [x*ncol + y]
8295 // using binary heap ...
83- Heap<uint32_t > openset (nrow*ncol);
84- openset.insert (0 , x1*ncol+y1);
96+ m_openset.insert (0 , x1*ncol+y1);
97+ // record the starting point in openset_grid
98+ m_openset_grid (x1,y1) = true ;
8599
86100 // The map of navigated nodes.
87101 HashTable<uint32_t , uint32_t > came_from (nrow*ncol);
88102
89- g_score (y1,x1 ) = 0 .0f ;
90- f_score (y1,x1 ) = g_score (y1,x1 ) + estimate (x1,y1,x2,y2);
103+ g_score (x1,y1 ) = 0 .0f ;
104+ f_score (x1,y1 ) = g_score (x1,y1 ) + estimate (x1,y1,x2,y2);
91105
92106 AStarResult * as = new AStarResult;
93107 as->path = NULL ;
94108 as->num_nodes = 0 ;
95109
96- while (!openset .is_empty ()) {
97- uint32_t value = openset .min_value ();
110+ while (!m_openset .is_empty ()) {
111+ uint32_t value = m_openset .min_value ();
98112 int cx = value/ncol;
99113 int cy = value%ncol;
100114
101115 if (cx == (int )x2 && cy==(int )y2) { // we reached (x2,y2)
102116 // reconstruct path & return
117+ as->num_nodes = 2 ;
103118 uint32_t tmp = x2*ncol+y2;
104119 while ((tmp=came_from[tmp]) != x1*ncol+y1) {
105120 as->num_nodes ++;
@@ -109,15 +124,20 @@ namespace alg {
109124
110125 tmp = x2*ncol+y2;
111126 int idx=0 ;
127+ as->path [idx++] = x2;
128+ as->path [idx++] = y2;
112129 while ((tmp=came_from[tmp]) != x1*ncol+y1) {
113130 as->path [idx++] = tmp/ncol;
114131 as->path [idx++] = tmp%ncol;
115132 }
133+ as->path [idx++] = x1;
134+ as->path [idx++] = y1;
116135 return as;
117136 }
118137
119- openset.delete_min ();
120- m_closedset (cy, cx) = true ;
138+ m_openset.delete_min ();
139+ m_closedset (cx, cy) = true ;
140+ m_openset_grid (cx, cy) = false ;
121141
122142 // for each neighbor
123143 int nx, ny;
@@ -127,26 +147,27 @@ namespace alg {
127147 if (ny<0 || ny>=(int )nrow) continue ;
128148
129149 // except the wall;
130- if (m_grid (ny,nx ) == WALL) continue ;
150+ if (m_grid (nx,ny ) == WALL) continue ;
131151 // except the cur itself
132152 if (nx == cx && ny==cy) continue ;
133153 // if neighbour in the closed set
134- if (m_closedset (ny,nx )) continue ;
154+ if (m_closedset (nx,ny )) continue ;
135155
136- float tentative = g_score (cy,cx );
156+ float tentative = g_score (cx,cy );
137157 if (nx == cx || ny == cy) {
138- tentative += 1 + m_grid (ny,nx );
158+ tentative += 1 + m_grid (nx,ny );
139159 } else {
140- tentative += (1 + m_grid (ny,nx )) * SQRT2;
160+ tentative += (1 + m_grid (nx,ny )) * SQRT2;
141161 }
142162
143163 // if neighbour not in the openset or dist < g_score[neighbour]
144- if (!openset. contains (nx*ncol+ ny) || tentative < g_score (ny,nx )) {
164+ if (!m_openset_grid (nx, ny) || tentative < g_score (nx,ny )) {
145165 came_from[nx*ncol+ny] = cx*ncol+cy; // record path
146- g_score (ny,nx) = tentative;
147- f_score (ny,nx) = tentative + estimate (nx,ny,x2,y2);
148- if (!openset.contains (nx*ncol+ny)) {
149- openset.insert (f_score (ny,nx), nx*ncol+ny);
166+ g_score (nx,ny) = tentative;
167+ f_score (nx,ny) = tentative + estimate (nx,ny,x2,y2);
168+ if (!m_openset_grid (nx,ny)) {
169+ m_openset.insert (f_score (nx,ny), nx*ncol+ny);
170+ m_openset_grid (nx,ny) = true ;
150171 }
151172 }
152173 }
0 commit comments