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//////////////////////////////////////////////////////////////////////////////
135template <typename TKSpace>
138DGtal::GridCurve<TKSpace>::initFromPointsVector( const std::vector<Point>& aVectorOfPoints )
141 return initFromPointsRange( aVectorOfPoints.begin(), aVectorOfPoints.end() );
142 } catch (DGtal::ConnectivityException& /*ce*/) {
143 throw ConnectivityException();
145 } catch (DGtal::InputException& /*ie*/) {
146 throw InputException();
151template <typename TKSpace>
152template <typename TIterator>
155DGtal::GridCurve<TKSpace>::initFromPointsRange( const TIterator& itb, const TIterator& ite )
164 for ( ; j != ite; ++i, ++j) {
169 if (v.norm(Vector::L_1) != 1) { //disconnected !
170 throw ConnectivityException();
172 SCell s = PointVectorTo1SCell(p,v);
173 if ( ! isInside( s ) ) { //out of space !
174 throw InputException();
176 mySCells.push_back( s );
183 Vector v(first - last);
184 if (v.norm(Vector::L_1) == 1) {
185 SCell s = PointVectorTo1SCell(last,v);
186 ASSERT( isInside( s ) ); //never out of space
187 mySCells.push_back( PointVectorTo1SCell(last,v) );
194template <typename TKSpace>
197DGtal::GridCurve<TKSpace>::initFromSCellsVector( const std::vector<SCell>& aVectorOfSCells )
200 return initFromSCellsRange( aVectorOfSCells.begin(), aVectorOfSCells.end() );
201 } catch (DGtal::ConnectivityException& /*ce*/) {
202 throw ConnectivityException();
204 } catch (DGtal::InputException& /*ie*/) {
205 throw InputException();
210template <typename TKSpace>
211template <typename TIterator>
214DGtal::GridCurve<TKSpace>::initFromSCellsRange( const TIterator& itb, const TIterator& ite )
223 SCell currentSCell = *it;
224 mySCells.push_back( currentSCell );
227 for (++it; it != ite; ++it)
230 SCell expectedS( myKPtr->sDirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
232 SCell s( myKPtr->sIndirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
234 if ( myKPtr->sKCoords(s) != myKPtr->sKCoords(expectedS) )
236 throw ConnectivityException();
238 if ( ! isInside( currentSCell ) )
240 throw InputException();
242 mySCells.push_back( currentSCell );
246 } else return false; //empty range
250//------------------------------------------------------------------------------
252template <typename TKSpace>
255DGtal::GridCurve<TKSpace>::initFromVectorStream(std::istream & in )
258 std::vector<Point> v = PointListReader<Point>
259 ::getPointsFromInputStream(in);
261 if (v.size() == 0) throw IOException();
264 return initFromPointsVector(v);
265 } catch (DGtal::ConnectivityException& /*ce*/) {
266 throw ConnectivityException();
268 } catch (DGtal::InputException& /*ie*/) {
269 throw InputException();
274template <typename TKSpace>
277DGtal::GridCurve<TKSpace>::writeVectorToStream( std::ostream & out )
279 PointsRange r = getPointsRange();
280 for (typename PointsRange::ConstIterator it = r.begin(), itEnd = r.end();
284 for (unsigned int k = 0; k < Point::dimension; ++k) {
291//------------------------------------------------------------------------------
293template <typename TKSpace>
296DGtal::GridCurve<TKSpace>::isClosed() const
298 SCell first = *mySCells.begin();
299 SCell last = *mySCells.rbegin();
300 SCell nextLast( myKPtr->sDirectIncident( last , *myKPtr->sDirs( last ) ) );
301 SCell previousFirst( myKPtr->sIndirectIncident( first, *myKPtr->sDirs( first ) ) );
302 return ( myKPtr->sKCoords(nextLast) == myKPtr->sKCoords(previousFirst) );
305template <typename TKSpace>
308DGtal::GridCurve<TKSpace>::isOpen() const
310 return (! isClosed() );
313//------------------------------------------------------------------------------
314template <typename TKSpace>
316typename DGtal::GridCurve<TKSpace>::ConstIterator
317DGtal::GridCurve<TKSpace>::begin() const
319 return mySCells.begin();
322template <typename TKSpace>
324typename DGtal::GridCurve<TKSpace>::ConstIterator
325DGtal::GridCurve<TKSpace>::end() const
327 return mySCells.end();
330template <typename TKSpace>
332typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
333DGtal::GridCurve<TKSpace>::rbegin() const
335 return mySCells.rbegin();
338template <typename TKSpace>
340typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
341DGtal::GridCurve<TKSpace>::rend() const
343 return mySCells.rend();
346template <typename TKSpace>
348typename DGtal::GridCurve<TKSpace>::SCell
349DGtal::GridCurve<TKSpace>::back() const
351 return mySCells.back();
354template <typename TKSpace>
357DGtal::GridCurve<TKSpace>::push_back( const SCell& aSCell )
362template <typename TKSpace>
365DGtal::GridCurve<TKSpace>::pushBack( const SCell& aSCell )
367 mySCells.push_back(aSCell);
370template <typename TKSpace>
372typename DGtal::GridCurve<TKSpace>::Storage::size_type
373DGtal::GridCurve<TKSpace>::size() const
375 return mySCells.size();
378//------------------------------------------------------------------------------
380template <typename TKSpace>
383DGtal::GridCurve<TKSpace>::selfDisplay ( std::ostream & out ) const
385 out << "[" << className() << "]" << std::endl;
386 for(unsigned int i=0; i< mySCells.size(); i++){
387 out << mySCells.at(i) << " ";
392//------------------------------------------------------------------------------
393template <typename TKSpace>
396DGtal::GridCurve<TKSpace>::className() const
408///////////////////////////////////////////////////////////////////////////////
409// Implementation of inline functions and external operators //
411template <typename TKSpace>
414DGtal::operator<< ( std::ostream & out,
415 const DGtal::GridCurve<TKSpace> & aObject )
417 aObject.selfDisplay ( out );
422///////////////////////////////////////////////////////////////////////////////