DGtal  1.5.beta
GridCurve.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file GridCurve.ih
19  * @author Tristan Roussillon (\c
20  * tristan.roussillon@liris.cnrs.fr ) Laboratoire d'InfoRmatique en
21  * Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS,
22  * France
23  *
24  *
25  * @date 2011/06/27
26  *
27  * @brief Implementation of inline methods defined in GridCurve.h
28  *
29  * This file is part of the DGtal library.
30  */
31 
32 ///////////////////////////////////////////////////////////////////////////////
33 // IMPLEMENTATION of inline methods.
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 //////////////////////////////////////////////////////////////////////////////
37 #include <cstdlib>
38 #include <iostream>
39 #include <sstream>
40 
41 //////////////////////////////////////////////////////////////////////////////
42 
43 template <typename TKSpace>
44 DGtal::GridCurve<TKSpace>::~GridCurve()
45 {
46  if (myFlagIsOwned)
47  delete myKPtr;
48 }
49 
50 template <typename TKSpace>
51 DGtal::GridCurve<TKSpace>::GridCurve()
52  : myKPtr( new KSpace() ), myFlagIsOwned( true )
53 {
54 }
55 
56 template <typename TKSpace>
57 DGtal::GridCurve<TKSpace>::GridCurve( ConstAlias<KSpace> aKSpace)
58  : myKPtr( &aKSpace ), myFlagIsOwned( false )
59 {
60 }
61 
62 template <typename TKSpace>
63 DGtal::GridCurve<TKSpace>::GridCurve( const GridCurve<KSpace> & aOther )
64  : myFlagIsOwned( aOther.myFlagIsOwned ), mySCells( aOther.mySCells )
65 {
66  if (myFlagIsOwned)
67  myKPtr = new KSpace( *aOther.myKPtr ); //owned copy
68  else
69  myKPtr = aOther.myKPtr; //copy of the alias
70 }
71 
72 template <typename TKSpace>
73 typename DGtal::GridCurve<TKSpace> &
74 DGtal::GridCurve<TKSpace>::operator=( const GridCurve<KSpace> & aOther )
75 {
76  if ( this != &aOther )
77  {
78  mySCells = aOther.mySCells;
79 
80  //free old space
81  if (myFlagIsOwned)
82  delete myKPtr;
83  //acquire new space
84  myFlagIsOwned = aOther.myFlagIsOwned;
85  if (myFlagIsOwned)
86  myKPtr = new KSpace( *aOther.myKPtr ); //owned copy
87  else
88  myKPtr = aOther.myKPtr; //copy of the alias
89  }
90  return *this;
91 }
92 
93 template <typename TKSpace>
94 inline
95 bool
96 DGtal::GridCurve<TKSpace>::isValid() const
97 {
98  return ( (myKPtr != NULL)
99  && ( mySCells.size() > 0 ) );
100 }
101 
102 
103 ///////////////////////////////////////////////////////////////////////////////
104 // private methods //
105 
106 template <typename TKSpace>
107 inline
108 typename DGtal::GridCurve<TKSpace>::SCell
109 DGtal::GridCurve<TKSpace>::PointVectorTo1SCell(const Point& aPoint, const Vector& aVector)
110 {
111  ASSERT( (aVector.norm(Vector::L_1) == 1) );
112 
113  SCell pointel( myKPtr->sPointel(aPoint,myKPtr->NEG) );
114 
115  typename KSpace::Space::Dimension d = 0;
116  while ( aVector[d] == 0 ) ++d;
117  return myKPtr->sIncident( pointel,d,(aVector[d]>0)?myKPtr->POS:myKPtr->NEG );
118 }
119 
120 template <typename TKSpace>
121 inline
122 bool
123 DGtal::GridCurve<TKSpace>::isInside(const SCell& aSCell) const
124 {
125  bool flag = true;
126  for (Dimension k = 0; ( (k < KSpace::dimension)&&(flag) ); ++k)
127  {
128  flag = myKPtr->sIsInside( aSCell, k );
129  }
130  return flag;
131 }
132 
133 //////////////////////////////////////////////////////////////////////////////
134 
135 //deprecated
136 template <typename TKSpace>
137 inline
138 bool
139 DGtal::GridCurve<TKSpace>::initFromVector( const std::vector<Point>& aVectorOfPoints )
140 {
141  return initFromPointsVector( aVectorOfPoints );
142 }
143 
144 template <typename TKSpace>
145 inline
146 bool
147 DGtal::GridCurve<TKSpace>::initFromPointsVector( const std::vector<Point>& aVectorOfPoints )
148 {
149  try {
150  return initFromPointsRange( aVectorOfPoints.begin(), aVectorOfPoints.end() );
151  } catch (DGtal::ConnectivityException& /*ce*/) {
152  throw ConnectivityException();
153  return false;
154  } catch (DGtal::InputException& /*ie*/) {
155  throw InputException();
156  return false;
157  }
158 }
159 
160 template <typename TKSpace>
161 template <typename TIterator>
162 inline
163 bool
164 DGtal::GridCurve<TKSpace>::initFromPointsRange( const TIterator& itb, const TIterator& ite )
165 {
166 
167  mySCells.clear();
168 
169  TIterator i = itb;
170  TIterator j = itb;
171  ++j;
172 
173  for ( ; j != ite; ++i, ++j) {
174 
175  Point p = *i;
176  Vector v = *j - p;
177 
178  if (v.norm(Vector::L_1) != 1) { //disconnected !
179  throw ConnectivityException();
180  }
181  SCell s = PointVectorTo1SCell(p,v);
182  if ( ! isInside( s ) ) { //out of space !
183  throw InputException();
184  }
185  mySCells.push_back( s );
186 
187  }
188 
189 
190  Point first = *itb;
191  Point last = *i;
192  Vector v(first - last);
193  if (v.norm(Vector::L_1) == 1) {
194  SCell s = PointVectorTo1SCell(last,v);
195  ASSERT( isInside( s ) ); //never out of space
196  mySCells.push_back( PointVectorTo1SCell(last,v) );
197  }
198 
199  return true;
200 }
201 
202 
203 template <typename TKSpace>
204 inline
205 bool
206 DGtal::GridCurve<TKSpace>::initFromSCellsVector( const std::vector<SCell>& aVectorOfSCells )
207 {
208  try {
209  return initFromSCellsRange( aVectorOfSCells.begin(), aVectorOfSCells.end() );
210  } catch (DGtal::ConnectivityException& /*ce*/) {
211  throw ConnectivityException();
212  return false;
213  } catch (DGtal::InputException& /*ie*/) {
214  throw InputException();
215  return false;
216  }
217 }
218 
219 template <typename TKSpace>
220 template <typename TIterator>
221 inline
222 bool
223 DGtal::GridCurve<TKSpace>::initFromSCellsRange( const TIterator& itb, const TIterator& ite )
224 {
225 
226  mySCells.clear();
227 
228  //first scell
229  TIterator it = itb;
230  if (it != ite)
231  {
232  SCell currentSCell = *it;
233  mySCells.push_back( currentSCell );
234 
235  //other scells
236  for (++it; it != ite; ++it)
237  {
238 
239  SCell expectedS( myKPtr->sDirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
240  currentSCell = *it;
241  SCell s( myKPtr->sIndirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
242 
243  if ( myKPtr->sKCoords(s) != myKPtr->sKCoords(expectedS) )
244  { //disconnected !
245  throw ConnectivityException();
246  }
247  if ( ! isInside( currentSCell ) )
248  { //out of space !
249  throw InputException();
250  }
251  mySCells.push_back( currentSCell );
252  }
253 
254  return true;
255  } else return false; //empty range
256 
257 }
258 
259 //------------------------------------------------------------------------------
260 
261 template <typename TKSpace>
262 inline
263 bool
264 DGtal::GridCurve<TKSpace>::initFromVectorStream(std::istream & in )
265 {
266 
267  std::vector<Point> v = PointListReader<Point>
268  ::getPointsFromInputStream(in);
269 
270  if (v.size() == 0) throw IOException();
271 
272  try {
273  return initFromPointsVector(v);
274  } catch (DGtal::ConnectivityException& /*ce*/) {
275  throw ConnectivityException();
276  return false;
277  } catch (DGtal::InputException& /*ie*/) {
278  throw InputException();
279  return false;
280  }
281 }
282 
283 template <typename TKSpace>
284 inline
285 void
286 DGtal::GridCurve<TKSpace>::writeVectorToStream( std::ostream & out )
287 {
288  PointsRange r = getPointsRange();
289  for (typename PointsRange::ConstIterator it = r.begin(), itEnd = r.end();
290  it != itEnd; ++it)
291  {
292  Point p = *it;
293  for (unsigned int k = 0; k < Point::dimension; ++k) {
294  out << p[k] << " ";
295  }
296  out << std::endl;
297  }
298 }
299 
300 //------------------------------------------------------------------------------
301 
302 template <typename TKSpace>
303 inline
304 bool
305 DGtal::GridCurve<TKSpace>::isClosed() const
306 {
307  SCell first = *mySCells.begin();
308  SCell last = *mySCells.rbegin();
309  SCell nextLast( myKPtr->sDirectIncident( last , *myKPtr->sDirs( last ) ) );
310  SCell previousFirst( myKPtr->sIndirectIncident( first, *myKPtr->sDirs( first ) ) );
311  return ( myKPtr->sKCoords(nextLast) == myKPtr->sKCoords(previousFirst) );
312 }
313 
314 template <typename TKSpace>
315 inline
316 bool
317 DGtal::GridCurve<TKSpace>::isOpen() const
318 {
319  return (! isClosed() );
320 }
321 
322 //------------------------------------------------------------------------------
323 template <typename TKSpace>
324 inline
325 typename DGtal::GridCurve<TKSpace>::ConstIterator
326 DGtal::GridCurve<TKSpace>::begin() const
327 {
328  return mySCells.begin();
329 }
330 
331 template <typename TKSpace>
332 inline
333 typename DGtal::GridCurve<TKSpace>::ConstIterator
334 DGtal::GridCurve<TKSpace>::end() const
335 {
336  return mySCells.end();
337 }
338 
339 template <typename TKSpace>
340 inline
341 typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
342 DGtal::GridCurve<TKSpace>::rbegin() const
343 {
344  return mySCells.rbegin();
345 }
346 
347 template <typename TKSpace>
348 inline
349 typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
350 DGtal::GridCurve<TKSpace>::rend() const
351 {
352  return mySCells.rend();
353 }
354 
355 template <typename TKSpace>
356 inline
357 typename DGtal::GridCurve<TKSpace>::SCell
358 DGtal::GridCurve<TKSpace>::back() const
359 {
360  return mySCells.back();
361 }
362 
363 template <typename TKSpace>
364 inline
365 void
366 DGtal::GridCurve<TKSpace>::push_back( const SCell& aSCell )
367 {
368  pushBack(aSCell);
369 }
370 
371 template <typename TKSpace>
372 inline
373 void
374 DGtal::GridCurve<TKSpace>::pushBack( const SCell& aSCell )
375 {
376  mySCells.push_back(aSCell);
377 }
378 
379 template <typename TKSpace>
380 inline
381 typename DGtal::GridCurve<TKSpace>::Storage::size_type
382 DGtal::GridCurve<TKSpace>::size() const
383 {
384  return mySCells.size();
385 }
386 
387 //------------------------------------------------------------------------------
388 
389 template <typename TKSpace>
390 inline
391 void
392 DGtal::GridCurve<TKSpace>::selfDisplay ( std::ostream & out ) const
393 {
394  out << "[" << className() << "]" << std::endl;
395  for(unsigned int i=0; i< mySCells.size(); i++){
396  out << mySCells.at(i) << " ";
397  }
398  out << std::endl;
399 }
400 
401 //------------------------------------------------------------------------------
402 template <typename TKSpace>
403 inline
404 std::string
405 DGtal::GridCurve<TKSpace>::className() const
406 {
407  return "GridCurve";
408 }
409 
410 
411 
412 
413 
414 
415 
416 
417 ///////////////////////////////////////////////////////////////////////////////
418 // Implementation of inline functions and external operators //
419 
420 template <typename TKSpace>
421 inline
422 std::ostream&
423 DGtal::operator<< ( std::ostream & out,
424  const DGtal::GridCurve<TKSpace> & aObject )
425 {
426  aObject.selfDisplay ( out );
427  return out;
428 }
429 
430 // //
431 ///////////////////////////////////////////////////////////////////////////////
432 
433