00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #ifndef MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
00028 # define MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH
00029 
00033 
00034 # include <vector>
00035 # include <mln/core/concept/browsing.hh>
00036 
00037 
00038 namespace mln
00039 {
00040 
00041   namespace canvas
00042   {
00043 
00044     namespace browsing
00045     {
00046 
00048 
00076       struct snake_generic_t : public Browsing< snake_generic_t >
00077       {
00078 
00079         template <typename F>
00080         void operator()(F& f) const;
00081 
00082       };
00083 
00084       extern const snake_generic_t snake_generic;
00085 
00086 # ifndef MLN_INCLUDE_ONLY
00087 
00088 #  ifndef MLN_WO_GLOBAL_VARS
00089 
00090       const snake_generic_t snake_generic;
00091 
00092 #  endif // ! MLN_WO_GLOBAL_VARS
00093 
00094 
00095       template <typename F>
00096       inline
00097       void
00098       snake_generic_t::operator()(F& f) const
00099       {
00100         trace::entering("canvas::browsing::snake_generic");
00101         mln_precondition(f.input.is_valid());
00102 
00103         
00104         f.p = f.input.bbox().pmin();
00105 
00106         std::vector< int > directions(f.moves.size(), 0);
00107         unsigned deph = 0;
00108         unsigned total_deph = f.moves.size() / 2 + 1;
00109 
00110         
00111         f.init();
00112 
00113         bool first = true;
00114         directions[deph] = 1;
00115         deph = total_deph - 1;
00116 
00117         
00118         (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
00119         while (deph > 0) 
00120         {
00121           mln_assertion(deph <= total_deph);
00122           mln_assertion(deph > 0);
00123           
00124           if (!f.input.domain().has(f.p +
00125                                     f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]]))
00126           {
00127             
00128             deph--;
00129             if (deph >= 1)
00130               
00131               directions[deph] = directions[deph] == 1 ? 0 : 1;
00132             continue;
00133           }
00134 
00135           if (!first)
00136           {
00137             
00138             f.p += f.dps[(deph - 1) * 2 - 1 + directions[deph - 1]];
00139             
00140             (f.*(f.moves[(deph - 1) * 2 - 1 + directions[deph - 1]])) ();
00141           }
00142           else
00143             first = false;
00144 
00145           if (deph != total_deph)
00146           {
00147             
00148             deph++;
00149             first = true;
00150           }
00151         }
00152 
00153         trace::exiting("canvas::browsing::snake_generic");
00154       }
00155 
00156 # endif // ! MLN_INCLUDE_ONLY
00157 
00158     } 
00159 
00160   } 
00161 
00162 } 
00163 
00164 
00165 #endif // ! MLN_CANVAS_BROWSING_SNAKE_GENERIC_HH