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