File failed to load: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/config/TeX-MML-AM_CHTML/MathJax.js
DGtal 2.0.0
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
135template <typename TKSpace>
136inline
137bool
138DGtal::GridCurve<TKSpace>::initFromPointsVector( const std::vector<Point>& aVectorOfPoints )
139{
140 try {
141 return initFromPointsRange( aVectorOfPoints.begin(), aVectorOfPoints.end() );
142 } catch (DGtal::ConnectivityException& /*ce*/) {
143 throw ConnectivityException();
144 return false;
145 } catch (DGtal::InputException& /*ie*/) {
146 throw InputException();
147 return false;
148 }
149}
150
151template <typename TKSpace>
152template <typename TIterator>
153inline
154bool
155DGtal::GridCurve<TKSpace>::initFromPointsRange( const TIterator& itb, const TIterator& ite )
156{
157
158 mySCells.clear();
159
160 TIterator i = itb;
161 TIterator j = itb;
162 ++j;
163
164 for ( ; j != ite; ++i, ++j) {
165
166 Point p = *i;
167 Vector v = *j - p;
168
169 if (v.norm(Vector::L_1) != 1) { //disconnected !
170 throw ConnectivityException();
171 }
172 SCell s = PointVectorTo1SCell(p,v);
173 if ( ! isInside( s ) ) { //out of space !
174 throw InputException();
175 }
176 mySCells.push_back( s );
177
178 }
179
180
181 Point first = *itb;
182 Point last = *i;
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) );
188 }
189
190 return true;
191}
192
193
194template <typename TKSpace>
195inline
196bool
197DGtal::GridCurve<TKSpace>::initFromSCellsVector( const std::vector<SCell>& aVectorOfSCells )
198{
199 try {
200 return initFromSCellsRange( aVectorOfSCells.begin(), aVectorOfSCells.end() );
201 } catch (DGtal::ConnectivityException& /*ce*/) {
202 throw ConnectivityException();
203 return false;
204 } catch (DGtal::InputException& /*ie*/) {
205 throw InputException();
206 return false;
207 }
208}
209
210template <typename TKSpace>
211template <typename TIterator>
212inline
213bool
214DGtal::GridCurve<TKSpace>::initFromSCellsRange( const TIterator& itb, const TIterator& ite )
215{
216
217 mySCells.clear();
218
219 //first scell
220 TIterator it = itb;
221 if (it != ite)
222 {
223 SCell currentSCell = *it;
224 mySCells.push_back( currentSCell );
225
226 //other scells
227 for (++it; it != ite; ++it)
228 {
229
230 SCell expectedS( myKPtr->sDirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
231 currentSCell = *it;
232 SCell s( myKPtr->sIndirectIncident( currentSCell, *myKPtr->sDirs( currentSCell ) ) );
233
234 if ( myKPtr->sKCoords(s) != myKPtr->sKCoords(expectedS) )
235 { //disconnected !
236 throw ConnectivityException();
237 }
238 if ( ! isInside( currentSCell ) )
239 { //out of space !
240 throw InputException();
241 }
242 mySCells.push_back( currentSCell );
243 }
244
245 return true;
246 } else return false; //empty range
247
248}
249
250//------------------------------------------------------------------------------
251
252template <typename TKSpace>
253inline
254bool
255DGtal::GridCurve<TKSpace>::initFromVectorStream(std::istream & in )
256{
257
258 std::vector<Point> v = PointListReader<Point>
259 ::getPointsFromInputStream(in);
260
261 if (v.size() == 0) throw IOException();
262
263 try {
264 return initFromPointsVector(v);
265 } catch (DGtal::ConnectivityException& /*ce*/) {
266 throw ConnectivityException();
267 return false;
268 } catch (DGtal::InputException& /*ie*/) {
269 throw InputException();
270 return false;
271 }
272}
273
274template <typename TKSpace>
275inline
276void
277DGtal::GridCurve<TKSpace>::writeVectorToStream( std::ostream & out )
278{
279 PointsRange r = getPointsRange();
280 for (typename PointsRange::ConstIterator it = r.begin(), itEnd = r.end();
281 it != itEnd; ++it)
282 {
283 Point p = *it;
284 for (unsigned int k = 0; k < Point::dimension; ++k) {
285 out << p[k] << " ";
286 }
287 out << std::endl;
288 }
289}
290
291//------------------------------------------------------------------------------
292
293template <typename TKSpace>
294inline
295bool
296DGtal::GridCurve<TKSpace>::isClosed() const
297{
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) );
303}
304
305template <typename TKSpace>
306inline
307bool
308DGtal::GridCurve<TKSpace>::isOpen() const
309{
310 return (! isClosed() );
311}
312
313//------------------------------------------------------------------------------
314template <typename TKSpace>
315inline
316typename DGtal::GridCurve<TKSpace>::ConstIterator
317DGtal::GridCurve<TKSpace>::begin() const
318{
319 return mySCells.begin();
320}
321
322template <typename TKSpace>
323inline
324typename DGtal::GridCurve<TKSpace>::ConstIterator
325DGtal::GridCurve<TKSpace>::end() const
326{
327 return mySCells.end();
328}
329
330template <typename TKSpace>
331inline
332typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
333DGtal::GridCurve<TKSpace>::rbegin() const
334{
335 return mySCells.rbegin();
336}
337
338template <typename TKSpace>
339inline
340typename DGtal::GridCurve<TKSpace>::ConstReverseIterator
341DGtal::GridCurve<TKSpace>::rend() const
342{
343 return mySCells.rend();
344}
345
346template <typename TKSpace>
347inline
348typename DGtal::GridCurve<TKSpace>::SCell
349DGtal::GridCurve<TKSpace>::back() const
350{
351 return mySCells.back();
352}
353
354template <typename TKSpace>
355inline
356void
357DGtal::GridCurve<TKSpace>::push_back( const SCell& aSCell )
358{
359 pushBack(aSCell);
360}
361
362template <typename TKSpace>
363inline
364void
365DGtal::GridCurve<TKSpace>::pushBack( const SCell& aSCell )
366{
367 mySCells.push_back(aSCell);
368}
369
370template <typename TKSpace>
371inline
372typename DGtal::GridCurve<TKSpace>::Storage::size_type
373DGtal::GridCurve<TKSpace>::size() const
374{
375 return mySCells.size();
376}
377
378//------------------------------------------------------------------------------
379
380template <typename TKSpace>
381inline
382void
383DGtal::GridCurve<TKSpace>::selfDisplay ( std::ostream & out ) const
384{
385 out << "[" << className() << "]" << std::endl;
386 for(unsigned int i=0; i< mySCells.size(); i++){
387 out << mySCells.at(i) << " ";
388 }
389 out << std::endl;
390}
391
392//------------------------------------------------------------------------------
393template <typename TKSpace>
394inline
395std::string
396DGtal::GridCurve<TKSpace>::className() const
397{
398 return "GridCurve";
399}
400
401
402
403
404
405
406
407
408///////////////////////////////////////////////////////////////////////////////
409// Implementation of inline functions and external operators //
410
411template <typename TKSpace>
412inline
413std::ostream&
414DGtal::operator<< ( std::ostream & out,
415 const DGtal::GridCurve<TKSpace> & aObject )
416{
417 aObject.selfDisplay ( out );
418 return out;
419}
420
421// //
422///////////////////////////////////////////////////////////////////////////////
423
424