1 #ifndef GEODESIC_ALGORITHM_GRAPH_BASE_010907 2 #define GEODESIC_ALGORITHM_GRAPH_BASE_010907 4 #include "geodesic_algorithm_base.h" 5 #include "geodesic_mesh_elements.h" 12 class GeodesicAlgorithmGraphBase:
public GeodesicAlgorithmBase
15 typedef Node* node_pointer;
17 GeodesicAlgorithmGraphBase(geodesic::Mesh* mesh):
18 GeodesicAlgorithmBase(mesh)
21 ~GeodesicAlgorithmGraphBase(){};
23 void propagate(std::vector<SurfacePoint>& sources,
24 double max_propagation_distance = GEODESIC_INF,
25 std::vector<SurfacePoint>* stop_points = NULL);
27 void trace_back(SurfacePoint& destination,
28 std::vector<SurfacePoint>& path);
30 unsigned best_source(SurfacePoint& point,
31 double& best_source_distance);
33 void print_statistics()
35 GeodesicAlgorithmBase::print_statistics();
37 double memory = m_nodes.size()*
sizeof(Node);
38 std::cout <<
"uses about " << memory/1e6 <<
"Mb of memory" <<std::endl;
42 unsigned node_index(vertex_pointer v)
47 void set_sources(std::vector<SurfacePoint>& sources)
52 node_pointer best_first_node(SurfacePoint& point,
double& best_total_distance)
54 node_pointer best_node = NULL;
55 if(point.type() == VERTEX)
57 vertex_pointer v = (vertex_pointer)point.base_element();
58 best_node = &m_nodes[node_index(v)];
59 best_total_distance = best_node->distance_from_source();
63 std::vector<node_pointer> possible_nodes;
64 list_nodes_visible_from_source(point.base_element(), possible_nodes);
66 best_total_distance = GEODESIC_INF;
67 for(
unsigned i=0; i<possible_nodes.size(); ++i)
69 node_pointer node = possible_nodes[i];
71 double distance_from_dest = node->distance(&point);
72 if(node->distance_from_source() + distance_from_dest < best_total_distance)
74 best_total_distance = node->distance_from_source() + distance_from_dest;
82 if(best_total_distance > m_propagation_distance_stopped)
84 best_total_distance = GEODESIC_INF;
93 bool check_stop_conditions(
unsigned& index);
95 virtual void list_nodes_visible_from_source(MeshElementBase* p,
96 std::vector<node_pointer>& storage) = 0;
98 virtual void list_nodes_visible_from_node(node_pointer node,
99 std::vector<node_pointer>& storage,
100 std::vector<double>& distances,
101 double threshold_distance) = 0;
103 std::vector<Node> m_nodes;
105 typedef std::set<node_pointer, Node> queue_type;
108 std::vector<SurfacePoint> m_sources;
112 void GeodesicAlgorithmGraphBase<Node>::propagate(std::vector<SurfacePoint>& sources,
113 double max_propagation_distance,
114 std::vector<SurfacePoint>* stop_points)
116 set_stop_conditions(stop_points, max_propagation_distance);
117 set_sources(sources);
120 m_propagation_distance_stopped = GEODESIC_INF;
121 for(
unsigned i=0; i<m_nodes.size(); ++i)
126 clock_t start = clock();
128 std::vector<node_pointer> visible_nodes;
129 for(
unsigned i=0; i<m_sources.size(); ++i)
131 SurfacePoint* source = &m_sources[i];
132 list_nodes_visible_from_source(source->base_element(),
135 for(
unsigned j=0; j<visible_nodes.size(); ++j)
137 node_pointer node = visible_nodes[j];
138 double distance = node->distance(source);
139 if(distance < node->distance_from_source())
141 node->distance_from_source() = distance;
142 node->source_index() = i;
143 node->previous() = NULL;
146 visible_nodes.clear();
149 for(
unsigned i=0; i<m_nodes.size(); ++i)
151 if(m_nodes[i].distance_from_source() < GEODESIC_INF)
153 m_queue.insert(&m_nodes[i]);
157 unsigned counter = 0;
158 unsigned satisfied_index = 0;
160 std::vector<double> distances_between_nodes;
161 while(!m_queue.empty())
163 if(counter++ % 10 == 0)
165 if (check_stop_conditions(satisfied_index))
171 node_pointer min_node = *m_queue.begin();
172 m_queue.erase(m_queue.begin());
173 FEASSERT(min_node->distance_from_source() < GEODESIC_INF);
175 visible_nodes.clear();
176 distances_between_nodes.clear();
177 list_nodes_visible_from_node(min_node,
179 distances_between_nodes,
180 min_node->distance_from_source());
182 for(
unsigned i=0; i<visible_nodes.size(); ++i)
184 node_pointer next_node = visible_nodes[i];
186 if(next_node->distance_from_source() > min_node->distance_from_source() +
187 distances_between_nodes[i])
189 if(next_node->distance_from_source() < GEODESIC_INF)
191 typename queue_type::iterator iter = m_queue.find(next_node);
192 FEASSERT(iter != m_queue.end());
195 next_node->distance_from_source() = min_node->distance_from_source() +
196 distances_between_nodes[i];
197 next_node->source_index() = min_node->source_index();
198 next_node->previous() = min_node;
199 m_queue.insert(next_node);
204 m_propagation_distance_stopped = m_queue.empty() ? GEODESIC_INF : (*m_queue.begin())->distance_from_source();
205 clock_t finish = clock();
206 m_time_consumed = (
static_cast<double>(finish)-static_cast<double>(start))/CLOCKS_PER_SEC;
211 inline bool GeodesicAlgorithmGraphBase<Node>::check_stop_conditions(
unsigned& index)
213 double queue_min_distance = (*m_queue.begin())->distance_from_source();
215 if(queue_min_distance < m_max_propagation_distance)
220 while(index < m_stop_vertices.size())
222 vertex_pointer v = m_stop_vertices[index].first;
223 Node& node = m_nodes[node_index(v)];
224 if(queue_min_distance < node.distance_from_source() + m_stop_vertices[index].second)
234 inline void GeodesicAlgorithmGraphBase<Node>::trace_back(SurfacePoint& destination,
235 std::vector<SurfacePoint>& path)
239 double total_path_length;
240 node_pointer node = best_first_node(destination, total_path_length);
242 if(total_path_length>GEODESIC_INF/2.0)
247 path.push_back(destination);
249 if(node->distance(&destination) > 1e-50)
251 path.push_back(node->surface_point());
254 while(node->previous())
256 node = node->previous();
257 path.push_back(node->surface_point());
260 SurfacePoint& source = m_sources[node->source_index()];
261 if(node->distance(&source) > 1e-50)
263 path.push_back(source);
269 inline unsigned GeodesicAlgorithmGraphBase<Node>::best_source(SurfacePoint& point,
270 double& best_source_distance)
272 node_pointer node = best_first_node(point, best_source_distance);
273 return node ? node->source_index() : 0;
278 #endif //GEODESIC_ALGORITHM_GRAPH_BASE_010907 Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11