Loading [MathJax]/extensions/tex2jax.js
Free Electron
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
geodesic_cpp_mod/geodesic_algorithm_base.h
1 //Copyright (C) 2008 Danil Kirsanov, MIT License
2 
3 #ifndef GEODESIC_ALGORITHM_BASE_122806
4 #define GEODESIC_ALGORITHM_BASE_122806
5 
6 #include "geodesic_mesh.h"
7 #include "geodesic_constants_and_simple_functions.h"
8 #include <iostream>
9 #include <ctime>
10 
11 namespace geodesic{
12 
13 class GeodesicAlgorithmBase
14 {
15 public:
16  enum AlgorithmType
17  {
18  EXACT,
19  DIJKSTRA,
20  SUBDIVISION,
21  UNDEFINED_ALGORITHM
22  };
23 
24  GeodesicAlgorithmBase(geodesic::Mesh* mesh):
25  m_type(UNDEFINED_ALGORITHM),
26  m_max_propagation_distance(1e100),
27  m_mesh(mesh)
28  {};
29 
30  virtual ~GeodesicAlgorithmBase(){};
31 
32  virtual void propagate(std::vector<SurfacePoint>& sources,
33  double max_propagation_distance = GEODESIC_INF, //propagation algorithm stops after reaching the certain distance from the source
34  std::vector<SurfacePoint>* stop_points = NULL) = 0; //or after ensuring that all the stop_points are covered
35 
36  virtual void trace_back(SurfacePoint& destination, //trace back piecewise-linear path
37  std::vector<SurfacePoint>& path) = 0;
38 
39  void geodesic(SurfacePoint& source,
40  SurfacePoint& destination,
41  std::vector<SurfacePoint>& path); //lazy people can find geodesic path with one function call
42 
43  void geodesic(std::vector<SurfacePoint>& sources,
44  std::vector<SurfacePoint>& destinations,
45  std::vector<std::vector<SurfacePoint> >& paths); //lazy people can find geodesic paths with one function call
46 
47  virtual unsigned best_source(SurfacePoint& point, //after propagation step is done, quickly find what source this point belongs to and what is the distance to this source
48  double& best_source_distance) = 0;
49 
50  virtual void print_statistics() //print info about timing and memory usage in the propagation step of the algorithm
51  {
52  std::cout << "propagation step took " << m_time_consumed << " seconds " << std::endl;
53  };
54 
55  AlgorithmType type(){return m_type;};
56 
57  virtual std::string name();
58 
59  geodesic::Mesh* mesh(){return m_mesh;};
60 protected:
61 
62  void set_stop_conditions(std::vector<SurfacePoint>* stop_points,
63  double stop_distance);
64  double stop_distance()
65  {
66  return m_max_propagation_distance;
67  }
68 
69  AlgorithmType m_type; // type of the algorithm
70 
71  typedef std::pair<vertex_pointer, double> stop_vertex_with_distace_type;
72  std::vector<stop_vertex_with_distace_type> m_stop_vertices; // algorithm stops propagation after covering certain vertices
73  double m_max_propagation_distance; // or reaching the certain distance
74 
75  geodesic::Mesh* m_mesh;
76 
77  double m_time_consumed; //how much time does the propagation step takes
78  double m_propagation_distance_stopped; //at what distance (if any) the propagation algorithm stopped
79 };
80 
81 inline double length(std::vector<SurfacePoint>& path)
82 {
83  double length = 0;
84  if(!path.empty())
85  {
86  for(unsigned i=0; i<path.size()-1; ++i)
87  {
88  length += path[i].distance(&path[i+1]);
89  }
90  }
91  return length;
92 }
93 
94 inline void print_info_about_path(std::vector<SurfacePoint>& path)
95 {
96  std::cout << "number of the points in the path = " << path.size()
97  << ", length of the path = " << length(path)
98  << std::endl;
99 }
100 
101 inline std::string GeodesicAlgorithmBase::name()
102 {
103  switch(m_type)
104  {
105  case EXACT:
106  return "exact";
107  case DIJKSTRA:
108  return "dijkstra";
109  case SUBDIVISION:
110  return "subdivision";
111  default:
112  case UNDEFINED_ALGORITHM:
113  return "undefined";
114  }
115 }
116 
117 inline void GeodesicAlgorithmBase::geodesic(SurfacePoint& source,
118  SurfacePoint& destination,
119  std::vector<SurfacePoint>& path) //lazy people can find geodesic path with one function call
120 {
121  std::vector<SurfacePoint> sources(1, source);
122  std::vector<SurfacePoint> stop_points(1, destination);
123  double const max_propagation_distance = GEODESIC_INF;
124 
125  propagate(sources,
126  max_propagation_distance,
127  &stop_points);
128 
129  trace_back(destination, path);
130 }
131 
132 inline void GeodesicAlgorithmBase::geodesic(std::vector<SurfacePoint>& sources,
133  std::vector<SurfacePoint>& destinations,
134  std::vector<std::vector<SurfacePoint> >& paths) //lazy people can find geodesic paths with one function call
135 {
136  double const max_propagation_distance = GEODESIC_INF;
137 
138  propagate(sources,
139  max_propagation_distance,
140  &destinations); //we use desinations as stop points
141 
142  paths.resize(destinations.size());
143 
144  for(unsigned i=0; i<paths.size(); ++i)
145  {
146  trace_back(destinations[i], paths[i]);
147  }
148 }
149 
150 inline void GeodesicAlgorithmBase::set_stop_conditions(std::vector<SurfacePoint>* stop_points,
151  double stop_distance)
152 {
153  m_max_propagation_distance = stop_distance;
154 
155  if(!stop_points)
156  {
157  m_stop_vertices.clear();
158  return;
159  }
160 
161  m_stop_vertices.resize(stop_points->size());
162 
163  std::vector<vertex_pointer> possible_vertices;
164  for(unsigned i = 0; i < stop_points->size(); ++i)
165  {
166  SurfacePoint* point = &(*stop_points)[i];
167 
168  possible_vertices.clear();
169  m_mesh->closest_vertices(point, &possible_vertices);
170 
171  vertex_pointer closest_vertex = NULL;
172  double min_distance = 1e100;
173  for(unsigned j = 0; j < possible_vertices.size(); ++j)
174  {
175  double distance = point->distance(possible_vertices[j]);
176  if(distance < min_distance)
177  {
178  min_distance = distance;
179  closest_vertex = possible_vertices[j];
180  }
181  }
182  FEASSERT(closest_vertex);
183 
184  m_stop_vertices[i].first = closest_vertex;
185  m_stop_vertices[i].second = min_distance;
186  }
187 }
188 
189 }//geodesic
190 
191 #endif //GEODESIC_ALGORITHM_BASE_122806
Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11