DGtal  1.5.beta
UmbrellaComputer.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 UmbrellaComputer.ih
19  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20  * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
21  *
22  * @date 2010/10/28
23  *
24  * Implementation of inline methods defined in UmbrellaComputer.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // ----------------------- Standard services ------------------------------
40 
41 //-----------------------------------------------------------------------------
42 template <typename TDigitalSurfaceTracker>
43 inline
44 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::~UmbrellaComputer()
45 {
46  if ( myTracker != 0 ) delete myTracker;
47 }
48 //-----------------------------------------------------------------------------
49 template <typename TDigitalSurfaceTracker>
50 inline
51 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::UmbrellaComputer()
52  : myTracker( 0 )
53 {
54 }
55 //-----------------------------------------------------------------------------
56 template <typename TDigitalSurfaceTracker>
57 inline
58 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::
59 UmbrellaComputer( const UmbrellaComputer<TDigitalSurfaceTracker> & other )
60  : myTracker( 0 )
61 {
62  if ( other.myTracker != 0 )
63  {
64  myTracker = new DigitalSurfaceTracker( *other.myTracker );
65  myState = other.myState;
66  }
67 }
68 //-----------------------------------------------------------------------------
69 template <typename TDigitalSurfaceTracker>
70 inline
71 DGtal::UmbrellaComputer<TDigitalSurfaceTracker> &
72 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::
73 operator=( const UmbrellaComputer<TDigitalSurfaceTracker> & other )
74 {
75  if ( this != &other )
76  {
77  if ( myTracker != 0 )
78  {
79  delete myTracker;
80  myTracker = 0;
81  }
82  if ( other.myTracker != 0 )
83  {
84  myTracker = new DigitalSurfaceTracker( *other.myTracker );
85  myState = other.myState;
86  }
87  }
88  return *this;
89 }
90 //-----------------------------------------------------------------------------
91 template <typename TDigitalSurfaceTracker>
92 void
93 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::init
94 ( const DigitalSurfaceTracker & tracker,
95  Dimension k, bool epsilon, Dimension j )
96 {
97  if ( myTracker != 0 )
98  delete myTracker;
99  myTracker = new DigitalSurfaceTracker( tracker );
100  ASSERT( space().isSpaceClosed()
101  && "[UmbrellaComputer] It is necessary to work with a closed cellular space since umbrellas use separators and pivots, which must exist for arbitrary surfels. Please build a closed KhalimskySpaceND for instance if you wish to work with faces in digital surfaces." );
102  myState.surfel = myTracker->current();
103  myState.k = k;
104  myState.epsilon = epsilon;
105  myState.j = j;
106 }
107 //-----------------------------------------------------------------------------
108 template <typename TDigitalSurfaceTracker>
109 inline
110 void
111 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::getState
112 ( State & aState ) const
113 {
114  ASSERT( myTracker != 0 );
115  aState = myState;
116 }
117 //-----------------------------------------------------------------------------
118 template <typename TDigitalSurfaceTracker>
119 inline
120 void
121 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::setState( const State & aState )
122 {
123  ASSERT( myTracker != 0 );
124  myTracker->move( aState.surfel );
125  myState = aState;
126 }
127 //-----------------------------------------------------------------------------
128 template <typename TDigitalSurfaceTracker>
129 inline
130 const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::State &
131 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::state() const
132 {
133  return myState;
134 }
135 //-----------------------------------------------------------------------------
136 template <typename TDigitalSurfaceTracker>
137 inline
138 const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::KSpace &
139 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::space() const
140 {
141  return myTracker->surface().space();
142 }
143 
144 ///////////////////////////////////////////////////////////////////////////////
145 // ----------------------- Accessor services ------------------------------
146 template <typename TDigitalSurfaceTracker>
147 inline
148 const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::Surfel &
149 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::surfel() const
150 {
151  ASSERT( myTracker != 0 );
152  ASSERT( myTracker->current() == myState.surfel );
153  return myState.surfel;
154 }
155 //-----------------------------------------------------------------------------
156 template <typename TDigitalSurfaceTracker>
157 inline
158 typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::SCell
159 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separator() const
160 {
161  ASSERT( myTracker != 0 );
162  return space().sIncident( surfel(),
163  separatorDir(),
164  separatorOrientation() );
165 }
166 //-----------------------------------------------------------------------------
167 template <typename TDigitalSurfaceTracker>
168 inline
169 typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::SCell
170 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::pivot() const
171 {
172  ASSERT( myTracker != 0 );
173  return space()->sDirectIncident( separator(), trackDir() );
174 }
175 //-----------------------------------------------------------------------------
176 template <typename TDigitalSurfaceTracker>
177 inline
178 DGtal::Dimension
179 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::orthDir() const
180 {
181  ASSERT( myTracker != 0 );
182  return myTracker->orthDir();
183 }
184 //-----------------------------------------------------------------------------
185 template <typename TDigitalSurfaceTracker>
186 inline
187 DGtal::Dimension
188 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::trackDir() const
189 {
190  return myState.j;
191 }
192 //-----------------------------------------------------------------------------
193 template <typename TDigitalSurfaceTracker>
194 inline
195 bool
196 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::trackOrientation() const
197 {
198  return space().sDirect( separator(), trackDir() );
199 }
200 //-----------------------------------------------------------------------------
201 template <typename TDigitalSurfaceTracker>
202 inline
203 DGtal::Dimension
204 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separatorDir() const
205 {
206  return myState.k;
207 }
208 //-----------------------------------------------------------------------------
209 template <typename TDigitalSurfaceTracker>
210 inline
211 bool
212 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separatorOrientation() const
213 {
214  return myState.epsilon;
215 }
216 ///////////////////////////////////////////////////////////////////////////////
217 // ----------------------- Pivoting services ------------------------------
218 //-----------------------------------------------------------------------------
219 template <typename TDigitalSurfaceTracker>
220 inline
221 unsigned int
222 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::next()
223 {
224  ASSERT( myTracker != 0 );
225 
226  DGtal::Dimension j = trackDir();
227  // Delta^mu_t = +p
228  bool mu = trackOrientation(); // m_space->sdirect( separator(), j );
229  SCell sp;
230  unsigned int code = myTracker->adjacent( sp, j, mu );
231  if ( code != 0 )
232  { // Then the face has a successor.
233  DGtal::Dimension i = orthDir();
234  SCell s = myTracker->current();
235  myState.j = myState.k; // m_track_dir = m_separator_dir;
236  myTracker->move( sp );
237  myState.surfel = sp;
238  if ( code != 2 ) // s and sp are not aligned.
239  {
240  bool track_direct_orientation
241  = space().sDirect( s, j );
242  bool nu = space().sDirect( sp, i );
243  myState.k = i; // m_separator_dir = i;
244  myState.epsilon = ( mu == track_direct_orientation ) ^ nu;
245  // m_separator_orientation = ( mu == track_direct_orientation ) ^ nu;
246  }
247  else
248  {
249  myState.k = j; //m_separator_dir = j;
250  myState.epsilon = ! mu; // m_separator_orientation = ! mu;
251  }
252  }
253  return code;
254 }
255 //-----------------------------------------------------------------------------
256 template <typename TDigitalSurfaceTracker>
257 inline
258 unsigned int
259 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::previous()
260 {
261  ASSERT( myTracker != 0 );
262 
263 // cerr << "[DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::previous()] begin" << endl;
264 
265 // cerr << "(f=" << face()
266 // << ",s=" << separator()
267 // << ",p=" << pivot()
268 // << ",i=" << m_tracker->orthDir()
269 // << ",j=" << trackDir()
270 // << ",k=" << separatorDir()
271 // << ",E=" << separatorOrientation()
272 // << ")";
273 // cerr << endl;
274  DGtal::Dimension j = trackDir();
275  // Delta^mu_t = +p
276  DGtal::Dimension i = orthDir();
277  bool mu = trackOrientation(); // m_space->sdirect( separator(), j );
278  SCell sp;
279  unsigned int code = myTracker->adjacent( sp, separatorDir(),
280  separatorOrientation() );
281  // Kn_sid sp = m_tracker->adjacent( m_separator_dir, m_separator_orientation );
282  // cerr << "(" << face() << "," << sp << ")";
283  if ( code != 0 )
284  { // Then the face has a successor.
285  DGtal::Dimension k = separatorDir();
286  myTracker->move( sp );
287  myState.surfel = sp;
288  myState.k = j;
289  myState.epsilon = mu;
290  myState.j = ( code != 2 )
291  ? i // s and sp are not aligned.
292  : k; // s and sp are aligned.
293  }
294 // cerr << "(f=" << face()
295 // << ",s=" << separator()
296 // << ",p=" << pivot()
297 // << ",i=" << m_tracker->orthDir()
298 // << ",j=" << trackDir()
299 // << ",k=" << separatorDir()
300 // << ",E=" << separatorOrientation()
301 // << ")";
302 // cerr << endl;
303 // cerr << "[DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::previous()] end" << endl;
304  return code;
305 }
306 
307 
308 //-----------------------------------------------------------------------------
309 template <typename TDigitalSurfaceTracker>
310 inline
311 bool
312 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::adjacent()
313 {
314  ASSERT( myTracker != 0 );
315  DGtal::Dimension old_j = trackDir(); // uint old_j = m_track_dir;
316  if ( previous() == 0 ) return false;
317  bool mu = trackOrientation(); // m_space->sdirect( separator(), m_track_dir );
318  myState.k = myState.j; // m_separator_dir = m_track_dir;
319  myState.epsilon = mu; // m_separator_orientation = mu;
320  myState.j = old_j; // m_track_dir = old_j;
321  return true;
322 }
323 
324 ///////////////////////////////////////////////////////////////////////////////
325 // Interface - public :
326 
327 /**
328  * Writes/Displays the object on an output stream.
329  * @param out the output stream where the object is written.
330  */
331 template <typename TDigitalSurfaceTracker>
332 inline
333 void
334 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::selfDisplay ( std::ostream & out ) const
335 {
336  out << "[UmbrellaComputer]";
337 }
338 
339 /**
340  * Checks the validity/consistency of the object.
341  * @return 'true' if the object is valid, 'false' otherwise.
342  */
343 template <typename TDigitalSurfaceTracker>
344 inline
345 bool
346 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::isValid() const
347 {
348  return true;
349 }
350 
351 
352 
353 ///////////////////////////////////////////////////////////////////////////////
354 // Implementation of inline functions //
355 
356 template <typename TDigitalSurfaceTracker>
357 inline
358 std::ostream&
359 DGtal::operator<< ( std::ostream & out,
360  const UmbrellaComputer<TDigitalSurfaceTracker> & object )
361 {
362  object.selfDisplay( out );
363  return out;
364 }
365 
366 // //
367 ///////////////////////////////////////////////////////////////////////////////
368 
369