DGtal 1.4.0
Loading...
Searching...
No Matches
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
43template <typename TKSpace>
44DGtal::GridCurve<TKSpace>::~GridCurve()
45{
46 if (myFlagIsOwned)
47 delete myKPtr;
48}
49
50template <typename TKSpace>
51DGtal::GridCurve<TKSpace>::GridCurve()
52 : myKPtr( new KSpace() ), myFlagIsOwned( true )
53{
54}
55
56template <typename TKSpace>
57DGtal::GridCurve<TKSpace>::GridCurve( ConstAlias<KSpace> aKSpace)
58 : myKPtr( &aKSpace ), myFlagIsOwned( false )
59{
60}
61
62template <typename TKSpace>
63DGtal::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
72template <typename TKSpace>
73typename DGtal::GridCurve<TKSpace> &
74DGtal::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
93template <typename TKSpace>
94inline
95bool
96DGtal::GridCurve<TKSpace>::isValid() const
97{
98 return ( (myKPtr != NULL)
99 && ( mySCells.size() > 0 ) );
100}
101
102
103///////////////////////////////////////////////////////////////////////////////
104// private methods //
105
106template <typename TKSpace>
107inline
108typename DGtal::GridCurve<TKSpace>::SCell
109DGtal::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
120template <typename TKSpace>
121inline
122bool
123DGtal::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
136template <typename TKSpace>
137inline
138bool
139DGtal::GridCurve<TKSpace>::initFromVector( const std::vector<Point>& aVectorOfPoints )
140{
141 return initFromPointsVector( aVectorOfPoints );
142}
143
144template <typename TKSpace>
145inline
146bool
147DGtal::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
160template <typename TKSpace>
161template <typename TIterator>
162inline
163bool
164DGtal::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
203template <typename TKSpace>
204inline
205bool
206DGtal::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
219template <typename TKSpace>
220template <typename TIterator>
221inline
222bool
223DGtal::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
261template <typename TKSpace>
262inline
263bool
264DGtal::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
283template <typename TKSpace>
284inline
285void
286DGtal::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
302template <typename TKSpace>
303inline
304bool
305DGtal::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
314template <typename TKSpace>
315inline
316bool
317DGtal::GridCurve<TKSpace>::isOpen() const
318{
319 return (! isClosed() );
320}
321
322//------------------------------------------------------------------------------
323template <typename TKSpace>
324inline
325typename DGtal::GridCurve<TKSpace>::ConstIterator
326DGtal::GridCurve<TKSpace>::begin() const
327{
328 return mySCells.begin();
329}
330
331template <typename TKSpace>
332inline
333typename DGtal::GridCurve<TKSpace>::ConstIterator
334DGtal::GridCurve<TKSpace>::end() const
335{
336 return mySCells.end();
337}
338
339template <typename TKSpace>
340inline
341typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
342DGtal::GridCurve<TKSpace>::rbegin() const
343{
344 return mySCells.rbegin();
345}
346
347template <typename TKSpace>
348inline
349typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
350DGtal::GridCurve<TKSpace>::rend() const
351{
352 return mySCells.rend();
353}
354
355template <typename TKSpace>
356inline
357typename DGtal::GridCurve<TKSpace>::SCell
358DGtal::GridCurve<TKSpace>::back() const
359{
360 return mySCells.back();
361}
362
363template <typename TKSpace>
364inline
365void
366DGtal::GridCurve<TKSpace>::push_back( const SCell& aSCell )
367{
368 pushBack(aSCell);
369}
370
371template <typename TKSpace>
372inline
373void
374DGtal::GridCurve<TKSpace>::pushBack( const SCell& aSCell )
375{
376 mySCells.push_back(aSCell);
377}
378
379template <typename TKSpace>
380inline
381typename DGtal::GridCurve<TKSpace>::Storage::size_type
382DGtal::GridCurve<TKSpace>::size() const
383{
384 return mySCells.size();
385}
386
387//------------------------------------------------------------------------------
388
389template <typename TKSpace>
390inline
391void
392DGtal::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//------------------------------------------------------------------------------
402template <typename TKSpace>
403inline
404std::string
405DGtal::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
420template <typename TKSpace>
421inline
422std::ostream&
423DGtal::operator<< ( std::ostream & out,
424 const DGtal::GridCurve<TKSpace> & aObject )
425{
426 aObject.selfDisplay ( out );
427 return out;
428}
429
430// //
431///////////////////////////////////////////////////////////////////////////////
432
433