DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
VoronoiMap.ih
1 
30 
31 #include <cstdlib>
32 #include <boost/lexical_cast.hpp>
34 
36 // IMPLEMENTATION of inline methods.
38 
40 // ----------------------- Standard services ------------------------------
41 
45 template <typename S,typename P,DGtal::uint32_t p>
46 inline
48  const PointPredicate & aPredicate):
49  myDomain(aDomain), myPointPredicate(aPredicate)
50 {
51 }
52 
53 
57 template <typename S, typename P,DGtal::uint32_t p>
58 inline
60 {
61 }
62 
63 template <typename S, typename P, DGtal::uint32_t p>
64 inline
67 {
68 
69  //We copy the image extent and translate the image domains to (0,..0)x(Upper-Lower)
70  myLowerBoundCopy = myDomain.lowerBound();
71  myUpperBoundCopy = myDomain.upperBound();
72 
73  Domain workingDomain(myLowerBoundCopy, myUpperBoundCopy);
74  OutputImage output ( myDomain );
75  OutputImage swap ( myDomain );
76 
77  //Point outside the domain
78  myInfinity = myDomain.upperBound() + Point::diagonal(1);
79 
80  //Init
81  for(typename Domain::ConstIterator it = myDomain.begin(), itend = myDomain.end();
82  it != itend;
83  ++it)
84  if ( myPointPredicate( *it))
85  output.setValue ( *it, myInfinity );
86  else
87  output.setValue ( *it, *it );
88 
89  //We process the remaining dimensions
90  for ( Dimension dim = 0; dim < S::dimension ; dim++ )
91  computeOtherSteps ( output, dim );
92 
93  return output;
94 }
95 
96 template <typename S, typename P,DGtal::uint32_t p>
97 inline
98 void
100  const Dimension dim ) const
101 {
102  std::string title = "Voro dimension " + boost::lexical_cast<string>( dim ) ;
103  trace.beginBlock ( title );
104 
105  typedef typename Domain::ConstSubRange::ConstIterator ConstDomIt;
106 
107  //We setup the subdomain iterator
108  //the iterator will scan dimension using the order:
109  // {n-1, n-2, ... 1} (we skip the '0' dimension).
110 
111  std::vector<Size> subdomain;
112  subdomain.reserve(S::dimension - 1);
113  for (unsigned int k = 0; k < S::dimension ; k++)
114  if ( (S::dimension - 1 - k) != dim)
115  subdomain.push_back( S::dimension - 1 - k );
116 
117  Domain localDomain(myLowerBoundCopy, myUpperBoundCopy);
118 
119  //We pre-init the stack site
120  std::vector<Point> Sites(myUpperBoundCopy[dim] - myLowerBoundCopy[dim], myInfinity);
121 
122  //We process the dimensions to construct a Point
123  for (ConstDomIt it = localDomain.subRange( subdomain ).begin(),
124  itend = localDomain.subRange( subdomain ).end();
125  it != itend; ++it)
126  {
127  computeOtherStep1D ( output, (*it), dim, Sites);
128  }
129 
130  trace.endBlock();
131 
132 }
133 
134 // //////////////////////////////////////////////////////////////////////:
135 // ////////////////////////// Other Phases
136 template <typename S,typename P, DGtal::uint32_t p>
137 void
139  const Point &startingPoint,
140  const Size dim,
141  std::vector<Point> &Sites) const
142 {
143  Point point = startingPoint;
144  Point endpoint = startingPoint;
145  Point psite;
146  int nbSites = -1;
147 
148  //endpoint of the 1D row
149  endpoint[dim] = myUpperBoundCopy[dim];
150 
151  //Pruning the list of sites (dim=0 implies no hibben sites)
152  if (dim==0)
153  {
154  for(Abscissa i = myLowerBoundCopy[dim] ; i <= myUpperBoundCopy[dim] ; i++)
155  {
156  psite = output(point);
157  if ( psite != myInfinity )
158  {
159  nbSites++;
160  Sites[nbSites] = psite;
161  }
162  point[dim] ++;
163  }
164  }
165  else
166  {
167  //Pruning the list of sites
168  for(Abscissa i = myLowerBoundCopy[dim] ; i <= myUpperBoundCopy[dim] ; i++)
169  {
170  psite = output(point);
171  if ( psite != myInfinity )
172  {
173  while ((nbSites >= 1) &&
174  ( myMetric.hiddenBy(Sites[nbSites-1], Sites[nbSites] ,
175  psite, startingPoint, endpoint, dim) ))
176  {
177  nbSites --;
178  }
179  nbSites++;
180  Sites[nbSites] = psite;
181  }
182  point[dim] ++;
183  }
184  }
185 
186  //No sites found
187  if (nbSites == -1)
188  return;
189 
190  int k = 0;
191 
192  //Rewriting
193  point[dim] = myLowerBoundCopy[dim];
194  for(Abscissa i = myLowerBoundCopy[dim] ; i <= myUpperBoundCopy[dim] ; i++)
195  {
196  while ( (k < nbSites) &&
197  ( myMetric.closest(point, Sites[k], Sites[k+1])
198  != SeparableMetric::FIRST ))
199  k++;
200 
201  output.setValue(point, Sites[k]);
202  point[dim]++;
203  }
204 }
205 
206 
207 // // //
208 // ///////////////////////////////////////////////////////////////////////////////
209 
210