2 #ifndef GEODESIC_ALGORITHM_EXACT_ELEMENTS_20071231 3 #define GEODESIC_ALGORITHM_EXACT_ELEMENTS_20071231 5 #include "geodesic_memory.h" 6 #include "geodesic_mesh_elements.h" 16 typedef Interval* interval_pointer;
17 typedef IntervalList* list_pointer;
34 double signal(
double x)
36 assert(x>=0.0 && x <= m_edge->length());
38 if(m_d == GEODESIC_INF)
44 double dx = x - m_pseudo_x;
47 return m_d + std::abs(dx);
51 return m_d + sqrt(dx*dx + m_pseudo_y*m_pseudo_y);
56 double max_distance(
double end)
58 if(m_d == GEODESIC_INF)
64 double a = std::abs(m_start - m_pseudo_x);
65 double b = std::abs(end - m_pseudo_x);
67 return a > b ? m_d + sqrt(a*a + m_pseudo_y*m_pseudo_y):
68 m_d + sqrt(b*b + m_pseudo_y*m_pseudo_y);
72 void compute_min_distance(
double stop)
74 assert(stop > m_start);
76 if(m_d == GEODESIC_INF)
80 else if(m_start > m_pseudo_x)
82 m_min = signal(m_start);
84 else if(stop < m_pseudo_x)
90 assert(m_pseudo_y<=0);
91 m_min = m_d - m_pseudo_y;
95 bool operator()(interval_pointer
const x, interval_pointer
const y)
const 97 if(x->min() != y->min())
99 return x->min() < y->min();
101 else if(x->start() != y->start())
103 return x->start() < y->start();
107 return x->edge()->id() < y->edge()->id();
113 return m_next ? m_next->start() : m_edge->length();
116 double hypotenuse(
double a,
double b)
118 return sqrt(a*a + b*b);
121 void find_closest_point(
double const x,
126 double& start(){
return m_start;};
127 double& d(){
return m_d;};
128 double& pseudo_x(){
return m_pseudo_x;};
129 double& pseudo_y(){
return m_pseudo_y;};
130 double& min(){
return m_min;};
131 interval_pointer& next(){
return m_next;};
132 edge_pointer& edge(){
return m_edge;};
133 DirectionType& direction(){
return m_direction;};
134 bool visible_from_source(){
return m_direction == FROM_SOURCE;};
135 unsigned& source_index(){
return m_source_index;};
137 void initialize(edge_pointer edge,
138 SurfacePoint* point = NULL,
139 unsigned source_index = 0);
148 interval_pointer m_next;
150 unsigned m_source_index;
151 DirectionType m_direction;
154 struct IntervalWithStop :
public Interval
157 double& stop(){
return m_stop;};
165 IntervalList(){m_first = NULL;};
173 void initialize(edge_pointer e)
179 interval_pointer covering_interval(
double offset)
181 assert(offset >= 0.0 && offset <= m_edge->length());
183 interval_pointer p = m_first;
184 while(p && p->stop() < offset)
192 void find_closest_point(SurfacePoint* point,
195 interval_pointer& interval)
197 interval_pointer p = m_first;
198 distance = GEODESIC_INF;
202 m_edge->local_coordinates(point, x, y);
206 if(p->min()<GEODESIC_INF)
209 p->find_closest_point(x, y, o, d);
221 unsigned number_of_intervals()
223 interval_pointer p = m_first;
233 interval_pointer last()
235 interval_pointer p = m_first;
246 double signal(
double x)
248 interval_pointer interval = covering_interval(x);
250 return interval ? interval->signal(x) : GEODESIC_INF;
253 interval_pointer& first(){
return m_first;};
254 edge_pointer& edge(){
return m_edge;};
256 interval_pointer m_first;
260 class SurfacePointWithIndex :
public SurfacePoint
263 unsigned index(){
return m_index;};
265 void initialize(SurfacePoint& p,
unsigned index)
267 SurfacePoint::initialize(p);
271 bool operator()(SurfacePointWithIndex* x, SurfacePointWithIndex* y)
const 273 assert(x->type() != UNDEFINED_POINT && y->type() !=UNDEFINED_POINT);
275 if(x->type() != y->type())
277 return x->type() < y->type();
281 return x->base_element()->id() < y->base_element()->id();
289 class SortedSources :
public std::vector<SurfacePointWithIndex>
292 typedef std::vector<SurfacePointWithIndex*> sorted_vector_type;
294 typedef sorted_vector_type::iterator sorted_iterator;
295 typedef std::pair<sorted_iterator, sorted_iterator> sorted_iterator_pair;
297 sorted_iterator_pair sources(base_pointer mesh_element)
299 m_search_dummy.base_element() = mesh_element;
301 return equal_range(m_sorted.begin(),
307 void initialize(std::vector<SurfacePoint>& sources)
309 resize(sources.size());
310 m_sorted.resize(sources.size());
311 for(
unsigned i=0; i<sources.size(); ++i)
313 SurfacePointWithIndex& p = *(begin() + i);
315 p.initialize(sources[i],i);
319 std::sort(m_sorted.begin(), m_sorted.end(), m_compare_less);
322 SurfacePointWithIndex& operator[](
unsigned i)
325 return *(begin() + i);
329 sorted_vector_type m_sorted;
330 SurfacePointWithIndex m_search_dummy;
331 SurfacePointWithIndex m_compare_less;
335 inline void Interval::find_closest_point(
double const rs,
340 if(m_d == GEODESIC_INF)
343 d_out = GEODESIC_INF;
347 double hc = -m_pseudo_y;
348 double rc = m_pseudo_x;
351 double local_epsilon = SMALLEST_INTERVAL_RATIO*m_edge->length();
352 if(std::abs(hs+hc) < local_epsilon)
357 d_out = signal(m_start) + std::abs(rs - m_start);
362 d_out = signal(end) + fabs(end - rs);
372 double ri = (rs*hc + hs*rc)/(hs+hc);
377 d_out = signal(m_start) + hypotenuse(m_start - rs, hs);
382 d_out = signal(end) + hypotenuse(end - rs, hs);
387 d_out = m_d + hypotenuse(rc - rs, hc + hs);
393 inline void Interval::initialize(edge_pointer edge,
394 SurfacePoint* source,
395 unsigned source_index)
399 m_direction = UNDEFINED_DIRECTION;
401 m_source_index = source_index;
408 m_min = GEODESIC_INF;
413 if(source->base_element()->type() == VERTEX)
415 if(source->base_element()->id() == edge->v0()->id())
422 else if(source->base_element()->id() == edge->v1()->id())
431 edge->local_coordinates(source, m_pseudo_x, m_pseudo_y);
432 m_pseudo_y = -m_pseudo_y;
434 compute_min_distance(stop());
439 #endif //GEODESIC_ALGORITHM_EXACT_ELEMENTS_20071231 Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11