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" 13 class GeodesicAlgorithmGraphBase:
public GeodesicAlgorithmBase
16 typedef Node* node_pointer;
18 GeodesicAlgorithmGraphBase(geodesic::Mesh* mesh):
19 GeodesicAlgorithmBase(mesh)
22 ~GeodesicAlgorithmGraphBase(){};
24 void propagate(std::vector<SurfacePoint>& sources,
25 double max_propagation_distance = GEODESIC_INF,
26 std::vector<SurfacePoint>* stop_points = NULL);
28 void trace_back(SurfacePoint& destination,
29 std::vector<SurfacePoint>& path);
31 unsigned best_source(SurfacePoint& point,
32 double& best_source_distance);
34 void print_statistics()
36 GeodesicAlgorithmBase::print_statistics();
38 double memory = m_nodes.size()*
sizeof(Node);
39 std::cout <<
"uses about " << memory/1e6 <<
"Mb of memory" <<std::endl;
43 unsigned node_index(vertex_pointer v)
48 void set_sources(std::vector<SurfacePoint>& sources)
53 node_pointer best_first_node(SurfacePoint& point,
double& best_total_distance)
55 node_pointer best_node = NULL;
56 if(point.type() == VERTEX)
58 vertex_pointer v = (vertex_pointer)point.base_element();
59 best_node = &m_nodes[node_index(v)];
60 best_total_distance = best_node->distance_from_source();
64 std::vector<node_pointer> possible_nodes;
65 list_nodes_visible_from_source(point.base_element(), possible_nodes);
67 best_total_distance = GEODESIC_INF;
68 for(
unsigned i=0; i<possible_nodes.size(); ++i)
70 node_pointer node = possible_nodes[i];
72 double distance_from_dest = node->distance(&point);
73 if(node->distance_from_source() + distance_from_dest < best_total_distance)
75 best_total_distance = node->distance_from_source() + distance_from_dest;
83 if(best_total_distance > m_propagation_distance_stopped)
85 best_total_distance = GEODESIC_INF;
94 bool check_stop_conditions(
unsigned& index);
96 virtual void list_nodes_visible_from_source(MeshElementBase* p,
97 std::vector<node_pointer>& storage) = 0;
99 virtual void list_nodes_visible_from_node(node_pointer node,
100 std::vector<node_pointer>& storage,
101 std::vector<double>& distances,
102 double threshold_distance) = 0;
104 std::vector<Node> m_nodes;
106 typedef std::set<node_pointer, Node> queue_type;
109 std::vector<SurfacePoint> m_sources;
113 void GeodesicAlgorithmGraphBase<Node>::propagate(std::vector<SurfacePoint>& sources,
114 double max_propagation_distance,
115 std::vector<SurfacePoint>* stop_points)
117 set_stop_conditions(stop_points, max_propagation_distance);
118 set_sources(sources);
121 m_propagation_distance_stopped = GEODESIC_INF;
122 for(
unsigned i=0; i<m_nodes.size(); ++i)
127 clock_t start = clock();
129 std::vector<node_pointer> visible_nodes;
130 for(
unsigned i=0; i<m_sources.size(); ++i)
132 SurfacePoint* source = &m_sources[i];
133 list_nodes_visible_from_source(source->base_element(),
136 for(
unsigned j=0; j<visible_nodes.size(); ++j)
138 node_pointer node = visible_nodes[j];
139 double distance = node->distance(source);
140 if(distance < node->distance_from_source())
142 node->distance_from_source() = distance;
143 node->source_index() = i;
144 node->previous() = NULL;
147 visible_nodes.clear();
150 for(
unsigned i=0; i<m_nodes.size(); ++i)
152 if(m_nodes[i].distance_from_source() < GEODESIC_INF)
154 m_queue.insert(&m_nodes[i]);
158 unsigned counter = 0;
159 unsigned satisfied_index = 0;
161 std::vector<double> distances_between_nodes;
162 while(!m_queue.empty())
164 if(counter++ % 10 == 0)
166 if (check_stop_conditions(satisfied_index))
172 node_pointer min_node = *m_queue.begin();
173 m_queue.erase(m_queue.begin());
174 assert(min_node->distance_from_source() < GEODESIC_INF);
176 visible_nodes.clear();
177 distances_between_nodes.clear();
178 list_nodes_visible_from_node(min_node,
180 distances_between_nodes,
181 min_node->distance_from_source());
183 for(
unsigned i=0; i<visible_nodes.size(); ++i)
185 node_pointer next_node = visible_nodes[i];
187 if(next_node->distance_from_source() > min_node->distance_from_source() +
188 distances_between_nodes[i])
190 if(next_node->distance_from_source() < GEODESIC_INF)
192 typename queue_type::iterator iter = m_queue.find(next_node);
193 assert(iter != m_queue.end());
196 next_node->distance_from_source() = min_node->distance_from_source() +
197 distances_between_nodes[i];
198 next_node->source_index() = min_node->source_index();
199 next_node->previous() = min_node;
200 m_queue.insert(next_node);
205 m_propagation_distance_stopped = m_queue.empty() ? GEODESIC_INF : (*m_queue.begin())->distance_from_source();
206 clock_t finish = clock();
207 m_time_consumed = (
static_cast<double>(finish)-static_cast<double>(start))/CLOCKS_PER_SEC;
212 inline bool GeodesicAlgorithmGraphBase<Node>::check_stop_conditions(
unsigned& index)
214 double queue_min_distance = (*m_queue.begin())->distance_from_source();
216 if(queue_min_distance < m_max_propagation_distance)
221 while(index < m_stop_vertices.size())
223 vertex_pointer v = m_stop_vertices[index].first;
224 Node& node = m_nodes[node_index(v)];
225 if(queue_min_distance < node.distance_from_source() + m_stop_vertices[index].second)
235 inline void GeodesicAlgorithmGraphBase<Node>::trace_back(SurfacePoint& destination,
236 std::vector<SurfacePoint>& path)
240 double total_path_length;
241 node_pointer node = best_first_node(destination, total_path_length);
243 if(total_path_length>GEODESIC_INF/2.0)
248 path.push_back(destination);
250 if(node->distance(&destination) > 1e-50)
252 path.push_back(node->surface_point());
255 while(node->previous())
257 node = node->previous();
258 path.push_back(node->surface_point());
261 SurfacePoint& source = m_sources[node->source_index()];
262 if(node->distance(&source) > 1e-50)
264 path.push_back(source);
270 inline unsigned GeodesicAlgorithmGraphBase<Node>::best_source(SurfacePoint& point,
271 double& best_source_distance)
273 node_pointer node = best_first_node(point, best_source_distance);
274 return node ? node->source_index() : 0;
279 #endif //GEODESIC_ALGORITHM_GRAPH_BASE_010907 Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11