-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathevg-thin.hh
More file actions
158 lines (111 loc) · 4.32 KB
/
evg-thin.hh
File metadata and controls
158 lines (111 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*********************************************************************
EVG-THIN v1.1: A Thinning Approximation to the Extended Voronoi Graph
Copyright (C) 2006 - Patrick Beeson (pbeeson@cs.utexas.edu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
*********************************************************************/
#ifndef evg_thin_hh
#define evg_thin_hh
#include <deque>
#include "datatypes.hh"
#include "heap.hh"
using namespace std;
/**
The thinning algorithm can be thought of as a "brush fire" where a
fire starts at every obstacle and burns into freespace. When two
fronts of the fire meet, they define a skeleton.
This particular algorithm has special purpose machinery to crete a
1 cell wide skeleton (stops a cell from "burning" if it is next to
two or more "fronts" of the fire.
I made a linear algorthim from the quadradic algorithm discussed in
the original thinning publication (see README).
I also added max and min parameters and a pruning operator to
remove spurs.
**/
class evg_thin {
public:
evg_thin(const grid_type&, float, float, bool, bool, int, int);
skeleton_type generate_skeleton();
void reset();
private:
grid_type original_grid;
int grid_size_x,grid_size_y;
float coastal_dist, prune_dist;
bool prune,location;
// Keeps track of distance to closest obstacle.
class dist_cell {
public:
int x,y;
float distance;
friend bool operator> (const dist_cell& d1, const dist_cell& d2) {
return d1.distance>d2.distance;
}
};
typedef vector <dist_cell> dist_col;
typedef vector <dist_col> dist_grid;
dist_grid distance_grid;
void calculate_distances();
/**
occupied: not-part of skeleton (either an obstacle or a "burned"
free cell. free: a free cell that has not yet been
examined. processing: a free cell that is in queue to be
examined (prevents multiple copies of a cell in a queue).
processed: a free cell that has been determined will never
"burn". unknown : neither occupied nor free (grey cells inthe
lpm).
**/
typedef enum {occupied, free, skel, processing, processed, unknown} State;
typedef vector < vector <State> > gridtype;
gridtype _step1_grid; //!< holds current state of thinning algorithm
//!< before step1
gridtype _step2_grid; //!< holds current state of thinning algorithm
//!< before step2
int robot_loc_x, robot_loc_y;
int _num_exits;
bool on_grid(int,int);
skeleton_type curr_skel; //!< final skeleton
skeleton_type _tmp_skel; //!< intermediate skeleton
uint _root_index; //!< index of skeleton tree root in _tmp_skel;
//////// Responsible for actual thinning algorithm.
int _closestx, _closesty; //!< closest point on skeleton to robot
float _distance; //!< distance of robot's closest skeletal point to
//!< nearest obstacle
void find_skel();
void initialize();
void thin();
class edge {
public:
edge(int i, int j) {
x=i;
y=j;
}
int x,y;
};
typedef deque<edge> queuetype;
queuetype _step1_queue; //!< holds cells to process in step1
queuetype _step2_queue; //!< holds cells to process in step2
State step(gridtype&, edge&, bool);
/////////////////////////
///////Responsible for building the data structure from the grid
void find_skel_edge();
void build_skel();
void crawl_grid();
void remove_final_spur();
void best_to_depth_first();
void best_to_depth_first_helper(int myindex, int parent_index);
void remove_branch(int index, int child_index=-1);
void remove_branch2(int index);
bool is_exit(const node& curr_node);
vector<node> find_neighbors(int x, int y);
};
#endif //evg_thin_hh