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.
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.
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/>.
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,
27 * @brief Implementation of inline methods defined in GridCurve.h
29 * This file is part of the DGtal library.
32 ///////////////////////////////////////////////////////////////////////////////
33 // IMPLEMENTATION of inline methods.
34 ///////////////////////////////////////////////////////////////////////////////
36 //////////////////////////////////////////////////////////////////////////////
41 //////////////////////////////////////////////////////////////////////////////
43 template <typename TKSpace>
44 DGtal::GridCurve<TKSpace>::~GridCurve()
50 template <typename TKSpace>
51 DGtal::GridCurve<TKSpace>::GridCurve()
52 : myKPtr( new KSpace() ), myFlagIsOwned( true )
56 template <typename TKSpace>
57 DGtal::GridCurve<TKSpace>::GridCurve( ConstAlias<KSpace> aKSpace)
58 : myKPtr( &aKSpace ), myFlagIsOwned( false )
62 template <typename TKSpace>
63 DGtal::GridCurve<TKSpace>::GridCurve( const GridCurve<KSpace> & aOther )
64 : myFlagIsOwned( aOther.myFlagIsOwned ), mySCells( aOther.mySCells )
67 myKPtr = new KSpace( *aOther.myKPtr ); //owned copy
69 myKPtr = aOther.myKPtr; //copy of the alias
72 template <typename TKSpace>
73 typename DGtal::GridCurve<TKSpace> &
74 DGtal::GridCurve<TKSpace>::operator=( const GridCurve<KSpace> & aOther )
76 if ( this != &aOther )
78 mySCells = aOther.mySCells;
84 myFlagIsOwned = aOther.myFlagIsOwned;
86 myKPtr = new KSpace( *aOther.myKPtr ); //owned copy
88 myKPtr = aOther.myKPtr; //copy of the alias
93 template <typename TKSpace>
96 DGtal::GridCurve<TKSpace>::isValid() const
98 return ( (myKPtr != NULL)
99 && ( mySCells.size() > 0 ) );
103 ///////////////////////////////////////////////////////////////////////////////
104 // private methods //
106 template <typename TKSpace>
108 typename DGtal::GridCurve<TKSpace>::SCell
109 DGtal::GridCurve<TKSpace>::PointVectorTo1SCell(const Point& aPoint, const Vector& aVector)
111 ASSERT( (aVector.norm(Vector::L_1) == 1) );
113 SCell pointel( myKPtr->sPointel(aPoint,myKPtr->NEG) );
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 );
120 template <typename TKSpace>
123 DGtal::GridCurve<TKSpace>::isInside(const SCell& aSCell) const
126 for (Dimension k = 0; ( (k < KSpace::dimension)&&(flag) ); ++k)
128 flag = myKPtr->sIsInside( aSCell, k );
133 //////////////////////////////////////////////////////////////////////////////
136 template <typename TKSpace>
139 DGtal::GridCurve<TKSpace>::initFromVector( const std::vector<Point>& aVectorOfPoints )
141 return initFromPointsVector( aVectorOfPoints );
144 template <typename TKSpace>
147 DGtal::GridCurve<TKSpace>::initFromPointsVector( const std::vector<Point>& aVectorOfPoints )
150 return initFromPointsRange( aVectorOfPoints.begin(), aVectorOfPoints.end() );
151 } catch (DGtal::ConnectivityException& /*ce*/) {
152 throw ConnectivityException();
154 } catch (DGtal::InputException& /*ie*/) {
155 throw InputException();
160 template <typename TKSpace>
161 template <typename TIterator>
164 DGtal::GridCurve<TKSpace>::initFromPointsRange( const TIterator& itb, const TIterator& ite )
173 for ( ; j != ite; ++i, ++j) {
178 if (v.norm(Vector::L_1) != 1) { //disconnected !
179 throw ConnectivityException();
181 SCell s = PointVectorTo1SCell(p,v);
182 if ( ! isInside( s ) ) { //out of space !
183 throw InputException();
185 mySCells.push_back( s );
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) );
203 template <typename TKSpace>
206 DGtal::GridCurve<TKSpace>::initFromSCellsVector( const std::vector<SCell>& aVectorOfSCells )
209 return initFromSCellsRange( aVectorOfSCells.begin(), aVectorOfSCells.end() );
210 } catch (DGtal::ConnectivityException& /*ce*/) {
211 throw ConnectivityException();
213 } catch (DGtal::InputException& /*ie*/) {
214 throw InputException();
219 template <typename TKSpace>
220 template <typename TIterator>
223 DGtal::GridCurve<TKSpace>::initFromSCellsRange( const TIterator& itb, const TIterator& ite )
232 SCell currentSCell = *it;
233 mySCells.push_back( currentSCell );
236 for (++it; it != ite; ++it)
239 SCell expectedS( myKPtr->sDirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
241 SCell s( myKPtr->sIndirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
243 if ( myKPtr->sKCoords(s) != myKPtr->sKCoords(expectedS) )
245 throw ConnectivityException();
247 if ( ! isInside( currentSCell ) )
249 throw InputException();
251 mySCells.push_back( currentSCell );
255 } else return false; //empty range
259 //------------------------------------------------------------------------------
261 template <typename TKSpace>
264 DGtal::GridCurve<TKSpace>::initFromVectorStream(std::istream & in )
267 std::vector<Point> v = PointListReader<Point>
268 ::getPointsFromInputStream(in);
270 if (v.size() == 0) throw IOException();
273 return initFromPointsVector(v);
274 } catch (DGtal::ConnectivityException& /*ce*/) {
275 throw ConnectivityException();
277 } catch (DGtal::InputException& /*ie*/) {
278 throw InputException();
283 template <typename TKSpace>
286 DGtal::GridCurve<TKSpace>::writeVectorToStream( std::ostream & out )
288 PointsRange r = getPointsRange();
289 for (typename PointsRange::ConstIterator it = r.begin(), itEnd = r.end();
293 for (unsigned int k = 0; k < Point::dimension; ++k) {
300 //------------------------------------------------------------------------------
302 template <typename TKSpace>
305 DGtal::GridCurve<TKSpace>::isClosed() const
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) );
314 template <typename TKSpace>
317 DGtal::GridCurve<TKSpace>::isOpen() const
319 return (! isClosed() );
322 //------------------------------------------------------------------------------
323 template <typename TKSpace>
325 typename DGtal::GridCurve<TKSpace>::ConstIterator
326 DGtal::GridCurve<TKSpace>::begin() const
328 return mySCells.begin();
331 template <typename TKSpace>
333 typename DGtal::GridCurve<TKSpace>::ConstIterator
334 DGtal::GridCurve<TKSpace>::end() const
336 return mySCells.end();
339 template <typename TKSpace>
341 typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
342 DGtal::GridCurve<TKSpace>::rbegin() const
344 return mySCells.rbegin();
347 template <typename TKSpace>
349 typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
350 DGtal::GridCurve<TKSpace>::rend() const
352 return mySCells.rend();
355 template <typename TKSpace>
357 typename DGtal::GridCurve<TKSpace>::SCell
358 DGtal::GridCurve<TKSpace>::back() const
360 return mySCells.back();
363 template <typename TKSpace>
366 DGtal::GridCurve<TKSpace>::push_back( const SCell& aSCell )
371 template <typename TKSpace>
374 DGtal::GridCurve<TKSpace>::pushBack( const SCell& aSCell )
376 mySCells.push_back(aSCell);
379 template <typename TKSpace>
381 typename DGtal::GridCurve<TKSpace>::Storage::size_type
382 DGtal::GridCurve<TKSpace>::size() const
384 return mySCells.size();
387 //------------------------------------------------------------------------------
389 template <typename TKSpace>
392 DGtal::GridCurve<TKSpace>::selfDisplay ( std::ostream & out ) const
394 out << "[" << className() << "]" << std::endl;
395 for(unsigned int i=0; i< mySCells.size(); i++){
396 out << mySCells.at(i) << " ";
401 //------------------------------------------------------------------------------
402 template <typename TKSpace>
405 DGtal::GridCurve<TKSpace>::className() const
417 ///////////////////////////////////////////////////////////////////////////////
418 // Implementation of inline functions and external operators //
420 template <typename TKSpace>
423 DGtal::operator<< ( std::ostream & out,
424 const DGtal::GridCurve<TKSpace> & aObject )
426 aObject.selfDisplay ( out );
431 ///////////////////////////////////////////////////////////////////////////////