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/>.
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
24 * Implementation of inline methods defined in UmbrellaComputer.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////
39 // ----------------------- Standard services ------------------------------
41 //-----------------------------------------------------------------------------
42 template <typename TDigitalSurfaceTracker>
44 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::~UmbrellaComputer()
46 if ( myTracker != 0 ) delete myTracker;
48 //-----------------------------------------------------------------------------
49 template <typename TDigitalSurfaceTracker>
51 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::UmbrellaComputer()
55 //-----------------------------------------------------------------------------
56 template <typename TDigitalSurfaceTracker>
58 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::
59 UmbrellaComputer( const UmbrellaComputer<TDigitalSurfaceTracker> & other )
62 if ( other.myTracker != 0 )
64 myTracker = new DigitalSurfaceTracker( *other.myTracker );
65 myState = other.myState;
68 //-----------------------------------------------------------------------------
69 template <typename TDigitalSurfaceTracker>
71 DGtal::UmbrellaComputer<TDigitalSurfaceTracker> &
72 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::
73 operator=( const UmbrellaComputer<TDigitalSurfaceTracker> & other )
82 if ( other.myTracker != 0 )
84 myTracker = new DigitalSurfaceTracker( *other.myTracker );
85 myState = other.myState;
90 //-----------------------------------------------------------------------------
91 template <typename TDigitalSurfaceTracker>
93 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::init
94 ( const DigitalSurfaceTracker & tracker,
95 Dimension k, bool epsilon, Dimension j )
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();
104 myState.epsilon = epsilon;
107 //-----------------------------------------------------------------------------
108 template <typename TDigitalSurfaceTracker>
111 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::getState
112 ( State & aState ) const
114 ASSERT( myTracker != 0 );
117 //-----------------------------------------------------------------------------
118 template <typename TDigitalSurfaceTracker>
121 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::setState( const State & aState )
123 ASSERT( myTracker != 0 );
124 myTracker->move( aState.surfel );
127 //-----------------------------------------------------------------------------
128 template <typename TDigitalSurfaceTracker>
130 const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::State &
131 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::state() const
135 //-----------------------------------------------------------------------------
136 template <typename TDigitalSurfaceTracker>
138 const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::KSpace &
139 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::space() const
141 return myTracker->surface().space();
144 ///////////////////////////////////////////////////////////////////////////////
145 // ----------------------- Accessor services ------------------------------
146 template <typename TDigitalSurfaceTracker>
148 const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::Surfel &
149 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::surfel() const
151 ASSERT( myTracker != 0 );
152 ASSERT( myTracker->current() == myState.surfel );
153 return myState.surfel;
155 //-----------------------------------------------------------------------------
156 template <typename TDigitalSurfaceTracker>
158 typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::SCell
159 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separator() const
161 ASSERT( myTracker != 0 );
162 return space().sIncident( surfel(),
164 separatorOrientation() );
166 //-----------------------------------------------------------------------------
167 template <typename TDigitalSurfaceTracker>
169 typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::SCell
170 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::pivot() const
172 ASSERT( myTracker != 0 );
173 return space()->sDirectIncident( separator(), trackDir() );
175 //-----------------------------------------------------------------------------
176 template <typename TDigitalSurfaceTracker>
179 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::orthDir() const
181 ASSERT( myTracker != 0 );
182 return myTracker->orthDir();
184 //-----------------------------------------------------------------------------
185 template <typename TDigitalSurfaceTracker>
188 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::trackDir() const
192 //-----------------------------------------------------------------------------
193 template <typename TDigitalSurfaceTracker>
196 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::trackOrientation() const
198 return space().sDirect( separator(), trackDir() );
200 //-----------------------------------------------------------------------------
201 template <typename TDigitalSurfaceTracker>
204 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separatorDir() const
208 //-----------------------------------------------------------------------------
209 template <typename TDigitalSurfaceTracker>
212 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separatorOrientation() const
214 return myState.epsilon;
216 ///////////////////////////////////////////////////////////////////////////////
217 // ----------------------- Pivoting services ------------------------------
218 //-----------------------------------------------------------------------------
219 template <typename TDigitalSurfaceTracker>
222 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::next()
224 ASSERT( myTracker != 0 );
226 DGtal::Dimension j = trackDir();
228 bool mu = trackOrientation(); // m_space->sdirect( separator(), j );
230 unsigned int code = myTracker->adjacent( sp, j, mu );
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 );
238 if ( code != 2 ) // s and sp are not aligned.
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;
249 myState.k = j; //m_separator_dir = j;
250 myState.epsilon = ! mu; // m_separator_orientation = ! mu;
255 //-----------------------------------------------------------------------------
256 template <typename TDigitalSurfaceTracker>
259 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::previous()
261 ASSERT( myTracker != 0 );
263 // cerr << "[DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::previous()] begin" << endl;
265 // cerr << "(f=" << face()
266 // << ",s=" << separator()
267 // << ",p=" << pivot()
268 // << ",i=" << m_tracker->orthDir()
269 // << ",j=" << trackDir()
270 // << ",k=" << separatorDir()
271 // << ",E=" << separatorOrientation()
274 DGtal::Dimension j = trackDir();
276 DGtal::Dimension i = orthDir();
277 bool mu = trackOrientation(); // m_space->sdirect( separator(), j );
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 << ")";
284 { // Then the face has a successor.
285 DGtal::Dimension k = separatorDir();
286 myTracker->move( sp );
289 myState.epsilon = mu;
290 myState.j = ( code != 2 )
291 ? i // s and sp are not aligned.
292 : k; // s and sp are aligned.
294 // cerr << "(f=" << face()
295 // << ",s=" << separator()
296 // << ",p=" << pivot()
297 // << ",i=" << m_tracker->orthDir()
298 // << ",j=" << trackDir()
299 // << ",k=" << separatorDir()
300 // << ",E=" << separatorOrientation()
303 // cerr << "[DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::previous()] end" << endl;
308 //-----------------------------------------------------------------------------
309 template <typename TDigitalSurfaceTracker>
312 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::adjacent()
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;
324 ///////////////////////////////////////////////////////////////////////////////
325 // Interface - public :
328 * Writes/Displays the object on an output stream.
329 * @param out the output stream where the object is written.
331 template <typename TDigitalSurfaceTracker>
334 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::selfDisplay ( std::ostream & out ) const
336 out << "[UmbrellaComputer]";
340 * Checks the validity/consistency of the object.
341 * @return 'true' if the object is valid, 'false' otherwise.
343 template <typename TDigitalSurfaceTracker>
346 DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::isValid() const
353 ///////////////////////////////////////////////////////////////////////////////
354 // Implementation of inline functions //
356 template <typename TDigitalSurfaceTracker>
359 DGtal::operator<< ( std::ostream & out,
360 const UmbrellaComputer<TDigitalSurfaceTracker> & object )
362 object.selfDisplay( out );
367 ///////////////////////////////////////////////////////////////////////////////