DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SegmentComputerUtils.h
1 
17 #pragma once
18 
34 #if defined(SegmentComputerUtils_RECURSES)
35 #error Recursive header files inclusion detected in SegmentComputerUtils.h
36 #else // defined(SegmentComputerUtils_RECURSES)
37 
38 #define SegmentComputerUtils_RECURSES
39 
40 #if !defined SegmentComputerUtils_h
41 
42 #define SegmentComputerUtils_h
43 
44 
45 #include "DGtal/base/Circulator.h"
46 
47 namespace DGtal
48 {
49 
51 // Categories
56 
57 
59 
69 //default
70 template <typename SC>
73 // typedef DynamicBidirectionalSegmentComputer Category;
74 // typedef BidirectionalSegmentComputer Category;
75 };
76 
77 
78 
80 // Useful functions for segment computers
81 
82 
86 template<typename IC>
87 IC getMiddleIterator(const IC& itb, const IC& ite, RandomAccessCategory)
88 {
89 //how to compute this with circulators ?
90 //return itb + ((ite-itb)/2);
91 //does not work
92  return getMiddleIterator(itb, ite, BidirectionalCategory() );
93 }
94 
99 template<typename IC>
100 IC getMiddleIterator(const IC& itb, const IC& ite, BidirectionalCategory)
101 {
102  IC b( itb );
103  IC f( ite );
104  bool flag = true;
105  while (b != f) {
106  if (flag) {
107  --f;
108  flag = false;
109  } else {
110  ++b;
111  flag = true;
112  }
113  }
114  return b;
115 }
116 
121 template<typename IC>
122 IC getMiddleIterator(const IC& itb, const IC& ite, ForwardCategory)
123 {
124  IC i( itb );
125 
126  unsigned int c = 0;
127  while (i != ite) {
128  ++i;
129  ++c;
130  }
131  unsigned int k = c/2;
132 
133  c = 0;
134  i = itb;
135  while (c != k) {
136  ++i;
137  ++c;
138  }
139 
140  return i;
141 }
149 template<typename IC>
150 IC getMiddleIterator(const IC& itb, const IC& ite) {
151  typedef typename IteratorCirculatorTraits<IC>::Category Category;
152  return getMiddleIterator(itb, ite, Category() );
153 }
154 
157 
158 
162 template <typename SC>
163 void maximalExtension(SC& s, const typename SC::ConstIterator& end, IteratorType ) {
164  //stop if s.end() == end
165  while ( (s.end() != end)
166  && (s.extendForward()) ) {}
167 }
168 
172 template <typename SC>
173 void maximalExtension(SC& s, const typename SC::ConstIterator& /*end*/, CirculatorType )
174 {
175  //stop if the segment is the whole range
176  const typename SC::ConstIterator newEnd( s.begin() );
177  while ( (s.extendForward())
178  && (s.end() != newEnd) ) {}
179 }
186 template <typename SC>
187 void maximalExtension(SC& s, const typename SC::ConstIterator& end) {
189  maximalExtension( s, end, Type() );
190 }
191 
192 
196 template <typename SC>
197 void oppositeEndMaximalExtension(SC& s, const typename SC::ConstIterator& begin, IteratorType ) {
198  //extend one more time if s.begin() == begin
199  while ( (s.begin() != begin)
200  && (s.extendBackward()) ) {}
201  if (s.begin() == begin) s.extendBackward();
202 }
203 
207 template <typename SC>
208 void oppositeEndMaximalExtension(SC& s, const typename SC::ConstIterator& begin, CirculatorType ) {
209  //stop if the segment is the whole range
210  const typename SC::ConstIterator newBegin( s.end() );
211  while ( (s.extendBackward())
212  && (s.begin() != newBegin) ) {}
213 }
214 
221 template <typename SC>
222 void oppositeEndMaximalExtension(SC& s, const typename SC::ConstIterator& begin) {
224  oppositeEndMaximalExtension( s, begin, Type() );
225 }
226 
227 
228 
232 template <typename SC>
234  const typename SC::ConstIterator& begin,
235  const typename SC::ConstIterator& end,
236  IteratorType ) {
237 
238  bool flagOk = true;
239  bool flagForward = true;
240  //while the extension is possible
241  //at the front and (then) at the back
242  while (flagOk) {
243  if (flagForward) {
244  flagForward = false;
245  if ( s.end() != end ) flagOk = s.extendForward();
246  else flagOk = false;
247  } else {
248  flagForward = true;
249  if ( s.begin() != begin ) flagOk = s.extendBackward();
250  else flagOk = false;
251  }
252  }
253  //extend one more time if s.begin() == begin
254  if (s.begin() != begin ) {
255  if (s.extendBackward()) return !s.extendForward();
256  else return false;
257  } else {
258  return !flagForward;
259  }
260 
261 }
262 
266 template <typename SC>
268  const typename SC::ConstIterator& begin,
269  const typename SC::ConstIterator& end,
270  CirculatorType ) {
271 
272  bool flagOk = true;
273  bool flagForward = true;
274  //while the extensions are possible and
275  //the segment does not correspond to the whole range
276  while ( (flagOk) && ( s.end() != s.begin() ) ) {
277  if (flagForward) {
278  flagForward = false;
279  flagOk = s.extendForward();
280  } else {
281  flagForward = true;
282  flagOk = s.extendBackward();
283  }
284  }
285  return !flagForward;
286 }
287 
297 template <typename SC>
299  const typename SC::ConstIterator& begin,
300  const typename SC::ConstIterator& end) {
301 
303  return maximalSymmetricExtension( s, begin, end, Type() );
304 
305 }
306 
307 
315 template <typename SC>
316 void maximalRetraction(SC& s, const typename SC::ConstIterator& end)
317 {
318  if ( isNotEmpty<typename SC::ConstIterator>(s.end(),end) ) {
319  while ( (! s.isExtendableForward() )
320  &&(s.retractForward() ) ) {}
321  } else {
322  while ( s.retractForward() ) {}
323  }
324 }
325 
333 template <typename SC>
334 void oppositeEndMaximalRetraction(SC& s, const typename SC::ConstIterator& begin)
335 {
336  if ( isNotEmpty<typename SC::ConstIterator>(s.begin(),begin) ) {
337  while ( (! s.isExtendableBackward() )
338  &&(s.retractBackward() ) ) {}
339  } else {
340  while ( s.retractBackward() ) {}
341  }
342 }
343 
346 
347 
351 template <typename SC>
352 void longestSegment(SC& s,
353  const typename SC::ConstIterator& i,
354  const typename SC::ConstIterator& end,
355  IteratorType )
356  {
357  if (i != end) {
358  s.init(i);
359  maximalExtension(s, end, IteratorType() );
360  }
361 }
362 
366 template <typename SC>
367 void longestSegment(SC& s,
368  const typename SC::ConstIterator& i,
369  const typename SC::ConstIterator& end,
370  CirculatorType )
371 {
372  s.init(i);
373  maximalExtension(s, end, CirculatorType() );
374 }
375 
383 template <typename SC>
384 void longestSegment(SC& s,
385  const typename SC::ConstIterator& i,
386  const typename SC::ConstIterator& end)
387 {
389  longestSegment( s, i, end, Type() );
390 }
391 
392 
395 
402 template <typename SC>
404  const typename SC::ConstIterator& i,
405  const typename SC::ConstIterator& begin,
406  const typename SC::ConstIterator& end,
408 {
409 
410  typedef typename SC::ConstIterator ConstIterator;
411  typedef typename SC::Reverse ReverseSegmentComputer;
412  typedef typename ReverseSegmentComputer::ConstIterator ConstReverseIterator;
413 
414  if ( isNotEmpty<ConstIterator>(i,end) ) {
415 
416  //backward extension
417  ConstIterator it( i ); ++it;
418  ConstReverseIterator rit( it );
419  ConstReverseIterator rend( begin );
420  ReverseSegmentComputer r( s.getReverse() );
421  longestSegment(r, rit, rend);
422 
423  //forward extension
424  ConstIterator it2( r.end().base() );
425  longestSegment(s, it2, end);
426 
427  }
428 
429 }
430 
437 template <typename SC>
439  const typename SC::ConstIterator& i,
440  const typename SC::ConstIterator& begin,
441  const typename SC::ConstIterator& end,
443 {
444  s.init(i);
445 
446  oppositeEndMaximalExtension(s, begin);
447  maximalExtension(s, end);
448 }
449 
457 template <typename SC>
459  const typename SC::ConstIterator& i,
460  const typename SC::ConstIterator& begin,
461  const typename SC::ConstIterator& end,
463 {
465 }
466 
474 template <typename SC>
476  const typename SC::ConstIterator& i,
477  const typename SC::ConstIterator& begin,
478  const typename SC::ConstIterator& end,
480 {
482 }
483 
490 template <typename SC>
492  const typename SC::ConstIterator& i,
493  const typename SC::ConstIterator& begin,
494  const typename SC::ConstIterator& end )
495 {
496  firstMaximalSegment<SC>(s, i, begin, end,
498 }
499 
502 
509 template <typename SC>
511  const typename SC::ConstIterator& i,
512  const typename SC::ConstIterator& begin,
513  const typename SC::ConstIterator& end,
515 {
516 
517  typedef typename SC::ConstIterator ConstIterator;
518  typedef typename SC::Reverse ReverseSegmentComputer;
519  typedef typename ReverseSegmentComputer::ConstIterator ConstReverseIterator;
520 
521  //get the first maximal segment passing through i
522 
523  firstMaximalSegment( s, i, begin, end, DGtal::ForwardSegmentComputer() );
524 
525  //get the next maximal segment while i is not at the middle of
526  //the current maximal segment.
527 
528  ConstIterator k( s.begin() );
529  while ( k != i ) {
530 
531  if ( isNotEmpty<ConstIterator>(s.end(),end) ) {
532 
533  //backward extension
534  ConstIterator it( s.end() ); ++it;
535  ConstReverseIterator rit( it );
536  ConstReverseIterator rend( s.begin() );
537  ReverseSegmentComputer r( s.getReverse() );
538  longestSegment(r, rit, rend);
539  ConstIterator newBegin = r.end().base();
540  ASSERT( newBegin != s.begin() );
541 
542  while ( ( k != getMiddleIterator(newBegin, s.end() ) )
543  &&( k != i ) ) {
544  ++k;
545  }
546  if ( k != i ) {
547 
548  //get the next maximal segment
549  longestSegment(s, newBegin, end);
550 
551  }
552 
553  } else {
554  k = i;
555  }
556  }
557 }
558 
565 template <typename SC>
567  const typename SC::ConstIterator& i,
568  const typename SC::ConstIterator& begin,
569  const typename SC::ConstIterator& end,
571 {
572 
573  if ( (isNotEmpty(i,end)) || (isNotEmpty(i,begin)) ) {
574 
575  s.init(i);
576 
577  //symmetric extension
578  if ( (isNotEmpty(i,end)) && (isNotEmpty(i,begin)) ) {
579  maximalSymmetricExtension(s, begin, end);
580  }
581 
582  //forward extension
583  maximalExtension(s, end);
584 
585  //backward extension
586  oppositeEndMaximalExtension(s, begin);
587 
588  }
589 
590 }
591 
599 template <typename SC>
601  const typename SC::ConstIterator& i,
602  const typename SC::ConstIterator& begin,
603  const typename SC::ConstIterator& end,
605 {
607 }
608 
616 template <typename SC>
618  const typename SC::ConstIterator& i,
619  const typename SC::ConstIterator& begin,
620  const typename SC::ConstIterator& end,
622 {
624 }
625 
632 template <typename SC>
634  const typename SC::ConstIterator& i,
635  const typename SC::ConstIterator& begin,
636  const typename SC::ConstIterator& end )
637 {
638  mostCenteredMaximalSegment<SC>(s, i, begin, end,
640 }
641 
644 
651 template <typename SC>
652 void lastMaximalSegment(SC& s,
653  const typename SC::ConstIterator& i,
654  const typename SC::ConstIterator& begin,
655  const typename SC::ConstIterator& end,
657 {
658 
659  typedef typename SC::ConstIterator ConstIterator;
660  typedef typename SC::Reverse ReverseSegmentComputer;
661  typedef typename ReverseSegmentComputer::ConstIterator ConstReverseIterator;
662 
663  //forward extension
664  ConstIterator j( i );
665  longestSegment(s, j, end);
666 
667  //backward extension
668  ConstIterator it( s.end() );
669  ConstReverseIterator rit( it );
670  ConstReverseIterator rend( begin );
671  ReverseSegmentComputer r( s.getReverse() );
672  longestSegment(r, rit, rend);
673 
674  //forward extension
675  ConstIterator it2( r.end().base() );
676  longestSegment(s, it2, end);
677 }
678 
685 template <typename SC>
686 void lastMaximalSegment(SC& s,
687  const typename SC::ConstIterator& i,
688  const typename SC::ConstIterator& begin,
689  const typename SC::ConstIterator& end,
691 {
692  s.init(i);
693 
694  maximalExtension(s, end);
695  oppositeEndMaximalExtension(s, begin);
696 }
697 
705 template <typename SC>
706 void lastMaximalSegment(SC& s,
707  const typename SC::ConstIterator& i,
708  const typename SC::ConstIterator& begin,
709  const typename SC::ConstIterator& end,
711 {
713 }
714 
722 template <typename SC>
723 void lastMaximalSegment(SC& s,
724  const typename SC::ConstIterator& i,
725  const typename SC::ConstIterator& begin,
726  const typename SC::ConstIterator& end,
728 {
730 }
731 
738 template <typename SC>
739 void lastMaximalSegment(SC& s,
740  const typename SC::ConstIterator& i,
741  const typename SC::ConstIterator& begin,
742  const typename SC::ConstIterator& end )
743 {
744  lastMaximalSegment<SC>(s, i, begin, end,
746 }
747 
750 
758 template <typename SC>
759 void nextMaximalSegment(SC& s,
760  const typename SC::ConstIterator& end,
762 {
763  firstMaximalSegment(s, s.end(), s.begin(), end, ForwardSegmentComputer() );
764 }
765 
773 template <typename SC>
774 void nextMaximalSegment(SC& s,
775  const typename SC::ConstIterator& end,
777 {
778  firstMaximalSegment(s, s.end(), s.begin(), end, DGtal::BidirectionalSegmentComputer() );
779 }
780 
787 template <typename SC>
788 void nextMaximalSegment(SC& s,
789  const typename SC::ConstIterator& end,
791 {
792  typedef typename SC::ConstIterator ConstIterator;
793 
794  //rectract
795  maximalRetraction(s, end);
796 
797  //intersection test
798  ConstIterator i( s.begin() ); ++i;
799  //if the intersection between the two
800  // consecutive maximal segments is empty
801  if ( i == s.end() ) {
802  if ( isNotEmpty<ConstIterator>(i, end) ) {
803  ++i;
804  s.init(i);
805  }
806  }
807 
808  //extend
809  maximalExtension(s, end);
810 }
811 
819 template <typename SC>
820 void nextMaximalSegment(SC& s,
821  const typename SC::ConstIterator& end,
823 {
825 }
826 
833 template <typename SC>
834 void nextMaximalSegment(SC& s,
835  const typename SC::ConstIterator& end )
836 {
837  nextMaximalSegment<SC>(s, end,
839 }
840 
843 
851 template <typename SC>
853  const typename SC::ConstIterator& begin,
855 {
856  if ( isNotEmpty<typename SC::ConstIterator>(s.begin(),begin) )
857  lastMaximalSegment(s, --s.begin(), begin, s.end(), DGtal::ForwardSegmentComputer() );
858 }
859 
867 template <typename SC>
869  const typename SC::ConstIterator& begin,
871 {
872  if ( isNotEmpty<typename SC::ConstIterator>(s.begin(),begin) )
873  lastMaximalSegment(s, --s.begin(), begin, s.end(), DGtal::BidirectionalSegmentComputer() );
874 }
875 
882 template <typename SC>
884  const typename SC::ConstIterator& begin,
886 {
887 
888  typedef typename SC::ConstIterator ConstIterator;
889 
890  //rectract
891  oppositeEndMaximalRetraction(s, begin);
892 
893  //intersection test
894  ConstIterator i( s.end() ); --i;
895  //if the intersection between the two
896  // consecutive maximal segments is empty
897  if ( i == s.begin() ) {
898  if ( isNotEmpty<ConstIterator>(i, begin) ) {
899  --i;
900  s.init(i);
901  }
902  }
903 
904  //extend
905  oppositeEndMaximalExtension(s, begin);
906 
907 }
908 
916 template <typename SC>
918  const typename SC::ConstIterator& end,
920 {
922 }
923 
930 template <typename SC>
932  const typename SC::ConstIterator& begin )
933 {
934  previousMaximalSegment(s, begin,
936 }
937 
938 } // namespace DGtal
939 
940 
941 
942 // //
944 
945 #endif // !defined SegmentComputerUtils_h
946 
947 #undef SegmentComputerUtils_RECURSES
948 #endif // else defined(SegmentComputerUtils_RECURSES)