DGtal  1.5.beta
ChordGenericNaivePlaneComputer.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 ChordGenericNaivePlaneComputer.ih
19  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20  * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
21  *
22  * @date 2012/09/20
23  *
24  * Implementation of inline methods defined in ChordGenericNaivePlaneComputer.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 TSpace, typename TInputPoint, typename TInternalScalar>
43 inline
44 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
45 ~ChordGenericNaivePlaneComputer()
46 { // Nothing to do.
47 }
48 //-----------------------------------------------------------------------------
49 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
50 inline
51 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
52 ChordGenericNaivePlaneComputer()
53 { // Object is invalid
54  _axesToErase.reserve( 3 );
55 }
56 //-----------------------------------------------------------------------------
57 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
58 inline
59 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
60 ChordGenericNaivePlaneComputer( const ChordGenericNaivePlaneComputer & other )
61  : myAxes( other.myAxes )
62 {
63  for ( AxisConstIterator it = myAxes.begin(), itE = myAxes.end();
64  it != itE; ++it )
65  myComputers[ *it ] = other.myComputers[ *it ];
66  _axesToErase.reserve( 3 );
67 }
68 //-----------------------------------------------------------------------------
69 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
70 inline
71 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar> &
72 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
73 operator=( const ChordGenericNaivePlaneComputer & other )
74 {
75  if ( this != &other )
76  {
77  myAxes = other.myAxes;
78  for ( AxisConstIterator it = myAxes.begin(), itE = myAxes.end();
79  it != itE; ++it )
80  myComputers[ *it ] = other.myComputers[ *it ];
81  }
82  return *this;
83 }
84 //-----------------------------------------------------------------------------
85 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
86 inline
87 DGtal::Dimension
88 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
89 active() const
90 {
91  ASSERT( myAxes.size() > 0 );
92  return myAxes[ 0 ];
93 }
94 //-----------------------------------------------------------------------------
95 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
96 inline
97 void
98 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
99 clear()
100 {
101  myAxes.clear();
102  for ( unsigned int i = 0; i < 3; ++i )
103  {
104  myAxes.push_back( i );
105  myComputers[ i ].clear();
106  }
107 }
108 //-----------------------------------------------------------------------------
109 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
110 inline
111 void
112 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
113 init( InternalScalar widthNumerator,
114  InternalScalar widthDenominator )
115 {
116  clear();
117  for ( unsigned int i = 0; i < 3; ++i )
118  myComputers[ i ].init( i, widthNumerator, widthDenominator );
119 }
120 //-----------------------------------------------------------------------------
121 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
122 inline
123 typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::Size
124 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
125 size() const
126 {
127  return myComputers[ active() ].size();
128 }
129 //-----------------------------------------------------------------------------
130 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
131 inline
132 bool
133 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
134 empty() const
135 {
136  return myComputers[ active() ].empty();
137 }
138 //-----------------------------------------------------------------------------
139 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
140 inline
141 typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::ConstIterator
142 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
143 begin() const
144 {
145  return myComputers[ active() ].begin();
146 }
147 //-----------------------------------------------------------------------------
148 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
149 inline
150 typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::ConstIterator
151 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
152 end() const
153 {
154  return myComputers[ active() ].end();
155 }
156 
157 //-----------------------------------------------------------------------------
158 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
159 inline
160 typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::Size
161 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
162 max_size() const
163 {
164  return myComputers[ active() ].max_size();
165 }
166 //-----------------------------------------------------------------------------
167 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
168 inline
169 typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::Size
170 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
171 maxSize() const
172 {
173  return max_size();
174 }
175 //-----------------------------------------------------------------------------
176 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
177 inline
178 bool
179 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
180 operator()( const Point & p ) const
181 {
182  return myComputers[ active() ].operator()( p );
183 }
184 
185 //-----------------------------------------------------------------------------
186 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
187 inline
188 bool
189 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
190 extendAsIs( const InputPoint & p )
191 {
192  ASSERT( isValid() );
193  unsigned int nbok = 0;
194  for ( AxisConstIterator it = myAxes.begin(), itE = myAxes.end();
195  it != itE; ++it )
196  {
197  nbok += myComputers[ *it ].operator()( p ) ? 1 : 0;
198  }
199  if ( nbok != 0 ) // at least one is ok.
200  {
201  for ( AxisIterator it = myAxes.begin(); it != myAxes.end(); )
202  // cannot put end() in variable, since end() moves when
203  // modifiying a vector.
204  {
205  bool ok = myComputers[ *it ].extendAsIs( p );
206  if ( ! ok )
207  it = myAxes.erase( it );
208  else
209  ++it;
210  }
211  ASSERT( ! myAxes.empty() );
212  return true;
213  }
214  return false;
215 }
216 
217 //-----------------------------------------------------------------------------
218 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
219 bool
220 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
221 extend( const InputPoint & p )
222 {
223  ASSERT( isValid() );
224  unsigned int nbok = 0;
225  _axesToErase.clear();
226  for ( AxisConstIterator axIt = myAxes.begin(), axItE = myAxes.end();
227  axIt != axItE; ++axIt )
228  {
229  bool ok = myComputers[ *axIt ].extend( p );
230  if ( ! ok ) _axesToErase.push_back( *axIt );
231  else ++nbok;
232  }
233  if ( nbok != 0 ) // at least one is ok.
234  { // if one is ok, we must remove ko ones from the list of active
235  // axes.
236  AxisIterator axIt = myAxes.begin();
237  for ( unsigned int i = 0; i < _axesToErase.size(); ++i )
238  {
239  while ( *axIt != _axesToErase[ i ] ) ++axIt;
240  axIt = myAxes.erase( axIt );
241  }
242  return true;
243  }
244  return false;
245 }
246 //-----------------------------------------------------------------------------
247 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
248 bool
249 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
250 isExtendable( const InputPoint & p ) const
251 {
252  ASSERT( isValid() );
253  unsigned int nbok = 0;
254  for ( AxisConstIterator it = myAxes.begin(), itE = myAxes.end();
255  it != itE; ++it )
256  {
257  nbok += myComputers[ *it ].isExtendable( p ) ? 1 : 0;
258  }
259  return nbok != 0;
260 }
261 //-----------------------------------------------------------------------------
262 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
263 template <typename TInputIterator>
264 bool
265 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
266 extend( TInputIterator it, TInputIterator itE )
267 {
268  BOOST_CONCEPT_ASSERT(( boost::InputIterator<TInputIterator> ));
269 
270  ASSERT( isValid() );
271  unsigned int nbok = 0;
272  _axesToErase.clear();
273  for ( AxisConstIterator axIt = myAxes.begin(), axItE = myAxes.end();
274  axIt != axItE; ++axIt )
275  {
276  bool ok = myComputers[ *axIt ].extend( it, itE );
277  if ( ! ok ) _axesToErase.push_back( *axIt );
278  else ++nbok;
279  }
280  if ( nbok != 0 ) // at least one is ok.
281  { // if one is ok, we must remove ko ones from the list of active
282  // axes.
283  AxisIterator axIt = myAxes.begin();
284  for ( unsigned int i = 0; i < _axesToErase.size(); ++i )
285  {
286  while ( *axIt != _axesToErase[ i ] ) ++axIt;
287  axIt = myAxes.erase( axIt );
288  }
289  return true;
290  }
291  return false;
292 }
293 //-----------------------------------------------------------------------------
294 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
295 template <typename TInputIterator>
296 bool
297 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
298 isExtendable( TInputIterator it, TInputIterator itE ) const
299 {
300  BOOST_CONCEPT_ASSERT(( boost::InputIterator<TInputIterator> ));
301 
302  ASSERT( isValid() );
303  unsigned int nbok = 0;
304  for ( AxisConstIterator axIt = myAxes.begin(), axItE = myAxes.end();
305  axIt != axItE; ++axIt )
306  {
307  nbok += myComputers[ *axIt ].isExtendable( it, itE ) ? 1 : 0;
308  }
309  return nbok != 0;
310 }
311 
312 //-----------------------------------------------------------------------------
313 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
314 inline
315 typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::Primitive
316 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
317 primitive() const
318 {
319  return myComputers[ active() ].primitive();
320 }
321 
322 //-----------------------------------------------------------------------------
323 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
324 template <typename Vector3D>
325 inline
326 void
327 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
328 getNormal( Vector3D & normal ) const
329 {
330  myComputers[ active() ].getNormal( normal );
331 }
332 //-----------------------------------------------------------------------------
333 //-----------------------------------------------------------------------------
334 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
335 template <typename Vector3D>
336 inline
337 void
338 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
339 getUnitNormal( Vector3D & normal ) const
340 {
341  myComputers[ active() ].getUnitNormal( normal );
342 }
343 //-----------------------------------------------------------------------------
344 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
345 inline
346 void
347 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
348 getBounds( double & min, double & max ) const
349 {
350  myComputers[ active() ].getBounds( min, max );
351 }
352 //-----------------------------------------------------------------------------
353 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
354 inline
355 const typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::InputPoint &
356 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
357 minimalPoint() const
358 {
359  return myComputers[ active() ].minimalPoint();
360 }
361 //-----------------------------------------------------------------------------
362 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
363 inline
364 const typename DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::InputPoint &
365 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::
366 maximalPoint() const
367 {
368  return myComputers[ active() ].maximalPoint();
369 }
370 
371 
372 
373 ///////////////////////////////////////////////////////////////////////////////
374 // Interface - public :
375 
376 /**
377  * Writes/Displays the object on an output stream.
378  * @param out the output stream where the object is written.
379  */
380 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
381 inline
382 void
383 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::selfDisplay ( std::ostream & out ) const
384 {
385  out << "[ChordGenericNaivePlaneComputer";
386  for ( AxisConstIterator axIt = myAxes.begin(), axItE = myAxes.end();
387  axIt != axItE; ++axIt )
388  out << " " << myComputers[ *axIt ];
389  out << " ]";
390 }
391 
392 /**
393  * Checks the validity/consistency of the object.
394  * @return 'true' if the object is valid, 'false' otherwise.
395  */
396 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
397 inline
398 bool
399 DGtal::ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar>::isValid() const
400 {
401  return myComputers[ active() ].isValid();
402 }
403 
404 
405 ///////////////////////////////////////////////////////////////////////////////
406 // Internals
407 ///////////////////////////////////////////////////////////////////////////////
408 
409 ///////////////////////////////////////////////////////////////////////////////
410 // Implementation of inline functions //
411 
412 template <typename TSpace, typename TInputPoint, typename TInternalScalar>
413 inline
414 std::ostream&
415 DGtal::operator<< ( std::ostream & out,
416  const ChordGenericNaivePlaneComputer<TSpace, TInputPoint, TInternalScalar> & object )
417 {
418  object.selfDisplay( out );
419  return out;
420 }
421 
422 // //
423 ///////////////////////////////////////////////////////////////////////////////