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" 15 typedef Interval* interval_pointer;
16 typedef IntervalList* list_pointer;
33 double signal(
double x)
35 FEASSERT(x>=0.0 && x <= m_edge->length());
37 if(m_d == GEODESIC_INF)
43 double dx = x - m_pseudo_x;
46 return m_d + std::abs(dx);
50 return m_d + sqrt(dx*dx + m_pseudo_y*m_pseudo_y);
55 double max_distance(
double end)
57 if(m_d == GEODESIC_INF)
63 double a = std::abs(m_start - m_pseudo_x);
64 double b = std::abs(end - m_pseudo_x);
66 return a > b ? m_d + sqrt(a*a + m_pseudo_y*m_pseudo_y):
67 m_d + sqrt(b*b + m_pseudo_y*m_pseudo_y);
71 void compute_min_distance(
double stop)
73 FEASSERT(stop > m_start);
75 if(m_d == GEODESIC_INF)
79 else if(m_start > m_pseudo_x)
81 m_min = signal(m_start);
83 else if(stop < m_pseudo_x)
89 FEASSERT(m_pseudo_y<=0);
90 m_min = m_d - m_pseudo_y;
94 bool operator()(interval_pointer
const x, interval_pointer
const y)
const 96 if(x->min() != y->min())
98 return x->min() < y->min();
100 else if(x->start() != y->start())
102 return x->start() < y->start();
106 return x->edge()->id() < y->edge()->id();
112 return m_next ? m_next->start() : m_edge->length();
115 double hypotenuse(
double a,
double b)
117 return sqrt(a*a + b*b);
120 void find_closest_point(
double const x,
125 double& start(){
return m_start;};
126 double& d(){
return m_d;};
127 double& pseudo_x(){
return m_pseudo_x;};
128 double& pseudo_y(){
return m_pseudo_y;};
129 double& min(){
return m_min;};
130 interval_pointer& next(){
return m_next;};
131 edge_pointer& edge(){
return m_edge;};
132 DirectionType& direction(){
return m_direction;};
133 bool visible_from_source(){
return m_direction == FROM_SOURCE;};
134 unsigned& source_index(){
return m_source_index;};
136 void initialize(edge_pointer edge,
137 SurfacePoint* point = NULL,
138 unsigned source_index = 0);
147 interval_pointer m_next;
149 unsigned m_source_index;
150 DirectionType m_direction;
153 struct IntervalWithStop :
public Interval
156 double& stop(){
return m_stop;};
164 IntervalList(){m_first = NULL;};
172 void initialize(edge_pointer e)
178 interval_pointer covering_interval(
double offset)
180 FEASSERT(offset >= 0.0 && offset <= m_edge->length());
182 interval_pointer p = m_first;
183 while(p && p->stop() < offset)
191 void find_closest_point(SurfacePoint* point,
194 interval_pointer& interval)
196 interval_pointer p = m_first;
197 distance = GEODESIC_INF;
201 m_edge->local_coordinates(point, x, y);
205 if(p->min()<GEODESIC_INF)
208 p->find_closest_point(x, y, o, d);
220 unsigned number_of_intervals()
222 interval_pointer p = m_first;
232 interval_pointer last()
234 interval_pointer p = m_first;
245 double signal(
double x)
247 interval_pointer interval = covering_interval(x);
249 return interval ? interval->signal(x) : GEODESIC_INF;
252 interval_pointer& first(){
return m_first;};
253 edge_pointer& edge(){
return m_edge;};
255 interval_pointer m_first;
259 class SurfacePointWithIndex :
public SurfacePoint
262 unsigned index(){
return m_index;};
264 void initialize(SurfacePoint& p,
unsigned index)
266 SurfacePoint::initialize(p);
270 bool operator()(SurfacePointWithIndex* x, SurfacePointWithIndex* y)
const 272 FEASSERT(x->type() != UNDEFINED_POINT && y->type() !=UNDEFINED_POINT);
274 if(x->type() != y->type())
276 return x->type() < y->type();
280 return x->base_element()->id() < y->base_element()->id();
288 class SortedSources :
public std::vector<SurfacePointWithIndex>
291 typedef std::vector<SurfacePointWithIndex*> sorted_vector_type;
293 typedef sorted_vector_type::iterator sorted_iterator;
294 typedef std::pair<sorted_iterator, sorted_iterator> sorted_iterator_pair;
296 sorted_iterator_pair sources(base_pointer mesh_element)
298 m_search_dummy.base_element() = mesh_element;
300 return equal_range(m_sorted.begin(),
306 void initialize(std::vector<SurfacePoint>& sources)
308 resize(sources.size());
309 m_sorted.resize(sources.size());
310 for(
unsigned i=0; i<sources.size(); ++i)
312 SurfacePointWithIndex& p = *(begin() + i);
314 p.initialize(sources[i],i);
318 std::sort(m_sorted.begin(), m_sorted.end(), m_compare_less);
321 SurfacePointWithIndex& operator[](
unsigned i)
323 FEASSERT(i < size());
324 return *(begin() + i);
328 sorted_vector_type m_sorted;
329 SurfacePointWithIndex m_search_dummy;
330 SurfacePointWithIndex m_compare_less;
334 inline void Interval::find_closest_point(
double const rs,
339 if(m_d == GEODESIC_INF)
342 d_out = GEODESIC_INF;
346 double hc = -m_pseudo_y;
347 double rc = m_pseudo_x;
350 double local_epsilon = SMALLEST_INTERVAL_RATIO*m_edge->length();
351 if(std::abs(hs+hc) < local_epsilon)
356 d_out = signal(m_start) + std::abs(rs - m_start);
361 d_out = signal(end) + fabs(end - rs);
371 double ri = (rs*hc + hs*rc)/(hs+hc);
376 d_out = signal(m_start) + hypotenuse(m_start - rs, hs);
381 d_out = signal(end) + hypotenuse(end - rs, hs);
386 d_out = m_d + hypotenuse(rc - rs, hc + hs);
392 inline void Interval::initialize(edge_pointer edge,
393 SurfacePoint* source,
394 unsigned source_index)
398 m_direction = UNDEFINED_DIRECTION;
400 m_source_index = source_index;
407 m_min = GEODESIC_INF;
412 if(source->base_element()->type() == VERTEX)
414 if(source->base_element()->id() == edge->v0()->id())
421 else if(source->base_element()->id() == edge->v1()->id())
430 edge->local_coordinates(source, m_pseudo_x, m_pseudo_y);
431 m_pseudo_y = -m_pseudo_y;
433 compute_min_distance(stop());
438 #endif //GEODESIC_ALGORITHM_EXACT_ELEMENTS_20071231 Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11