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//////////////////////////////////////////////////////////////////////////////
43template <typename TKSpace>
44DGtal::GridCurve<TKSpace>::~GridCurve()
50template <typename TKSpace>
51DGtal::GridCurve<TKSpace>::GridCurve()
52 : myKPtr( new KSpace() ), myFlagIsOwned( true )
56template <typename TKSpace>
57DGtal::GridCurve<TKSpace>::GridCurve( ConstAlias<KSpace> aKSpace)
58 : myKPtr( &aKSpace ), myFlagIsOwned( false )
62template <typename TKSpace>
63DGtal::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
72template <typename TKSpace>
73typename DGtal::GridCurve<TKSpace> &
74DGtal::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
93template <typename TKSpace>
96DGtal::GridCurve<TKSpace>::isValid() const
98 return ( (myKPtr != NULL)
99 && ( mySCells.size() > 0 ) );
103///////////////////////////////////////////////////////////////////////////////
106template <typename TKSpace>
108typename DGtal::GridCurve<TKSpace>::SCell
109DGtal::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 );
120template <typename TKSpace>
123DGtal::GridCurve<TKSpace>::isInside(const SCell& aSCell) const
126 for (Dimension k = 0; ( (k < KSpace::dimension)&&(flag) ); ++k)
128 flag = myKPtr->sIsInside( aSCell, k );
133//////////////////////////////////////////////////////////////////////////////
136template <typename TKSpace>
139DGtal::GridCurve<TKSpace>::initFromVector( const std::vector<Point>& aVectorOfPoints )
141 return initFromPointsVector( aVectorOfPoints );
144template <typename TKSpace>
147DGtal::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();
160template <typename TKSpace>
161template <typename TIterator>
164DGtal::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) );
203template <typename TKSpace>
206DGtal::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();
219template <typename TKSpace>
220template <typename TIterator>
223DGtal::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//------------------------------------------------------------------------------
261template <typename TKSpace>
264DGtal::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();
283template <typename TKSpace>
286DGtal::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//------------------------------------------------------------------------------
302template <typename TKSpace>
305DGtal::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) );
314template <typename TKSpace>
317DGtal::GridCurve<TKSpace>::isOpen() const
319 return (! isClosed() );
322//------------------------------------------------------------------------------
323template <typename TKSpace>
325typename DGtal::GridCurve<TKSpace>::ConstIterator
326DGtal::GridCurve<TKSpace>::begin() const
328 return mySCells.begin();
331template <typename TKSpace>
333typename DGtal::GridCurve<TKSpace>::ConstIterator
334DGtal::GridCurve<TKSpace>::end() const
336 return mySCells.end();
339template <typename TKSpace>
341typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
342DGtal::GridCurve<TKSpace>::rbegin() const
344 return mySCells.rbegin();
347template <typename TKSpace>
349typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
350DGtal::GridCurve<TKSpace>::rend() const
352 return mySCells.rend();
355template <typename TKSpace>
357typename DGtal::GridCurve<TKSpace>::SCell
358DGtal::GridCurve<TKSpace>::back() const
360 return mySCells.back();
363template <typename TKSpace>
366DGtal::GridCurve<TKSpace>::push_back( const SCell& aSCell )
371template <typename TKSpace>
374DGtal::GridCurve<TKSpace>::pushBack( const SCell& aSCell )
376 mySCells.push_back(aSCell);
379template <typename TKSpace>
381typename DGtal::GridCurve<TKSpace>::Storage::size_type
382DGtal::GridCurve<TKSpace>::size() const
384 return mySCells.size();
387//------------------------------------------------------------------------------
389template <typename TKSpace>
392DGtal::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//------------------------------------------------------------------------------
402template <typename TKSpace>
405DGtal::GridCurve<TKSpace>::className() const
417///////////////////////////////////////////////////////////////////////////////
418// Implementation of inline functions and external operators //
420template <typename TKSpace>
423DGtal::operator<< ( std::ostream & out,
424 const DGtal::GridCurve<TKSpace> & aObject )
426 aObject.selfDisplay ( out );
431///////////////////////////////////////////////////////////////////////////////