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//-----------------------------------------------------------------------------
42template <typename TDigitalSurfaceTracker>
44DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::~UmbrellaComputer()
46 if ( myTracker != 0 ) delete myTracker;
48//-----------------------------------------------------------------------------
49template <typename TDigitalSurfaceTracker>
51DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::UmbrellaComputer()
55//-----------------------------------------------------------------------------
56template <typename TDigitalSurfaceTracker>
58DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::
59UmbrellaComputer( const UmbrellaComputer<TDigitalSurfaceTracker> & other )
62 if ( other.myTracker != 0 )
64 myTracker = new DigitalSurfaceTracker( *other.myTracker );
65 myState = other.myState;
68//-----------------------------------------------------------------------------
69template <typename TDigitalSurfaceTracker>
71DGtal::UmbrellaComputer<TDigitalSurfaceTracker> &
72DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::
73operator=( const UmbrellaComputer<TDigitalSurfaceTracker> & other )
82 if ( other.myTracker != 0 )
84 myTracker = new DigitalSurfaceTracker( *other.myTracker );
85 myState = other.myState;
90//-----------------------------------------------------------------------------
91template <typename TDigitalSurfaceTracker>
93DGtal::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//-----------------------------------------------------------------------------
108template <typename TDigitalSurfaceTracker>
111DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::getState
112( State & aState ) const
114 ASSERT( myTracker != 0 );
117//-----------------------------------------------------------------------------
118template <typename TDigitalSurfaceTracker>
121DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::setState( const State & aState )
123 ASSERT( myTracker != 0 );
124 myTracker->move( aState.surfel );
127//-----------------------------------------------------------------------------
128template <typename TDigitalSurfaceTracker>
130const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::State &
131DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::state() const
135//-----------------------------------------------------------------------------
136template <typename TDigitalSurfaceTracker>
138const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::KSpace &
139DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::space() const
141 return myTracker->surface().space();
144///////////////////////////////////////////////////////////////////////////////
145// ----------------------- Accessor services ------------------------------
146template <typename TDigitalSurfaceTracker>
148const typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::Surfel &
149DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::surfel() const
151 ASSERT( myTracker != 0 );
152 ASSERT( myTracker->current() == myState.surfel );
153 return myState.surfel;
155//-----------------------------------------------------------------------------
156template <typename TDigitalSurfaceTracker>
158typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::SCell
159DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separator() const
161 ASSERT( myTracker != 0 );
162 return space().sIncident( surfel(),
164 separatorOrientation() );
166//-----------------------------------------------------------------------------
167template <typename TDigitalSurfaceTracker>
169typename DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::SCell
170DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::pivot() const
172 ASSERT( myTracker != 0 );
173 return space()->sDirectIncident( separator(), trackDir() );
175//-----------------------------------------------------------------------------
176template <typename TDigitalSurfaceTracker>
179DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::orthDir() const
181 ASSERT( myTracker != 0 );
182 return myTracker->orthDir();
184//-----------------------------------------------------------------------------
185template <typename TDigitalSurfaceTracker>
188DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::trackDir() const
192//-----------------------------------------------------------------------------
193template <typename TDigitalSurfaceTracker>
196DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::trackOrientation() const
198 return space().sDirect( separator(), trackDir() );
200//-----------------------------------------------------------------------------
201template <typename TDigitalSurfaceTracker>
204DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separatorDir() const
208//-----------------------------------------------------------------------------
209template <typename TDigitalSurfaceTracker>
212DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::separatorOrientation() const
214 return myState.epsilon;
216///////////////////////////////////////////////////////////////////////////////
217// ----------------------- Pivoting services ------------------------------
218//-----------------------------------------------------------------------------
219template <typename TDigitalSurfaceTracker>
222DGtal::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//-----------------------------------------------------------------------------
256template <typename TDigitalSurfaceTracker>
259DGtal::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//-----------------------------------------------------------------------------
309template <typename TDigitalSurfaceTracker>
312DGtal::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.
331template <typename TDigitalSurfaceTracker>
334DGtal::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.
343template <typename TDigitalSurfaceTracker>
346DGtal::UmbrellaComputer<TDigitalSurfaceTracker>::isValid() const
353///////////////////////////////////////////////////////////////////////////////
354// Implementation of inline functions //
356template <typename TDigitalSurfaceTracker>
359DGtal::operator<< ( std::ostream & out,
360 const UmbrellaComputer<TDigitalSurfaceTracker> & object )
362 object.selfDisplay( out );
367///////////////////////////////////////////////////////////////////////////////