DGtal  0.9.2
Naive3DDSSComputer.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 Naive3DDSSComputer.ih
19  * @author Kacper Pluta (\c kacper.pluta@esiee.fr )
20  * Laboratoire d'Informatique Gaspard-Monge - LIGM, A3SI, France
21  *
22  * @date 2014/10/07
23  *
24  * Implementation of inline methods defined in Naive3DDSSComputer.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 // IMPLEMENTATION of inline methods.
31 ///////////////////////////////////////////////////////////////////////////////
32 
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // Implementation of inline methods //
36 /**
37  * Default constructor.
38  * not valid
39  */
40 template <typename TIterator, typename TInteger, int connectivity>
41 inline
42 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Naive3DDSSComputer()
43 {
44  //projections
45  std::vector<DGtal::Dimension> v1,v2,v3;
46  v1.push_back(0);
47  v1.push_back(1);
48  v2.push_back(0);
49  v2.push_back(2);
50  v3.push_back(1);
51  v3.push_back(2);
52  myProjXY.init(v1.begin(),v1.end());
53  myProjXZ.init(v2.begin(),v2.end());
54  myProjYZ.init(v3.begin(),v3.end());
55  blockXY = blockXZ = blockYZ = false;
56 }
57 
58 /**
59  * Constructor with initialisation
60  */
61 template <typename TIterator, typename TInteger, int connectivity>
62 inline
63 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Naive3DDSSComputer(const ConstIterator& it)
64 {
65  //projections
66  std::vector<DGtal::Dimension> v1,v2,v3;
67  v1.push_back(0);
68  v1.push_back(1);
69  v2.push_back(0);
70  v2.push_back(2);
71  v3.push_back(1);
72  v3.push_back(2);
73  myProjXY.init(v1.begin(),v1.end());
74  myProjXZ.init(v2.begin(),v2.end());
75  myProjYZ.init(v3.begin(),v3.end());
76 
77  init(it);
78 }
79 
80 /**
81  * Initialisation.
82  * @param it an iterator on a sequence of points
83  */
84 template <typename TIterator, typename TInteger, int connectivity>
85 inline
86 void DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::init ( const ConstIterator& it )
87 {
88  //begin and end iterators
89  myBegin = it;
90  myEnd = it;
91  myEnd++;
92  //adapters and projections
93  IteratorAdapter XYit(it,myProjXY);
94  myXYalgo.init(XYit);
95  IteratorAdapter XZit(it,myProjXZ);
96  myXZalgo.init(XZit);
97  IteratorAdapter YZit(it,myProjYZ);
98  myYZalgo.init(YZit);
99  blockXY = blockXZ = blockYZ = false;
100 }
101 
102 /**
103  * Copy constructor.
104  * @param other the object to clone.
105  * Forbidden by default.
106  */
107 template <typename TIterator, typename TInteger, int connectivity>
108 inline
109 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Naive3DDSSComputer (
110  const Naive3DDSSComputer<TIterator,TInteger,connectivity> & other ) :
111  myProjXY(other.myProjXY), myProjXZ(other.myProjXZ), myProjYZ(other.myProjYZ),
112  myXYalgo(other.myXYalgo), myXZalgo(other.myXZalgo), myYZalgo(other.myYZalgo),
113  myBegin(other.myBegin), myEnd(other.myEnd)
114 {
115  blockXY = other.blockXY;
116  blockXZ = other.blockXZ;
117  blockYZ = other.blockYZ;
118 }
119 
120 /**
121  * Assignment.
122  * @param other the object to copy.
123  * @return a reference on 'this'.
124  * Forbidden by default.
125  */
126 template <typename TIterator, typename TInteger, int connectivity>
127 inline
128 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity> &
129 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::operator= (
130  const Naive3DDSSComputer<TIterator,TInteger,connectivity> & other )
131 {
132  myProjXY = other.myProjXY;
133  myProjXZ = other.myProjXZ;
134  myProjYZ = other.myProjYZ;
135  myXYalgo = other.myXYalgo;
136  myXZalgo = other.myXZalgo;
137  myYZalgo = other.myYZalgo;
138  myBegin = other.myBegin;
139  myEnd = other.myEnd;
140  blockXY = other.blockXY;
141  blockXZ = other.blockXZ;
142  blockYZ = other.blockYZ;
143  return *this;
144 }
145 
146 template <typename TIterator, typename TInteger, int connectivity>
147 inline
148 typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Self
149 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::getSelf() const
150 {
151  return Self();
152 }
153 
154 template <typename TIterator, typename TInteger, int connectivity>
155 inline
156 typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Reverse
157 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::getReverse() const
158 {
159  return Reverse();
160 }
161 
162 template <typename TIterator, typename TInteger, int connectivity>
163 inline
164 bool
165 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::isInDSS ( const Point3d & point) const
166 {
167  char test = 0;
168  if ( myXYalgo.isInDSS ( myProjXY ( point ) ) ) test++;
169  if ( myXZalgo.isInDSS ( myProjXZ ( point ) ) ) test++;
170  if ( myYZalgo.isInDSS ( myProjYZ ( point ) ) ) test++;
171  return test >= 2 ? true : false;
172 }
173 
174 template <typename TIterator, typename TInteger, int connectivity>
175 inline
176 bool
177 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::isInDSS ( const ConstIterator & it) const
178 {
179  char test = 0;
180  if ( myXYalgo.isInDSS ( myProjXY ( *it ) ) ) test++;
181  if ( myXZalgo.isInDSS ( myProjXZ ( *it ) ) ) test++;
182  if ( myYZalgo.isInDSS ( myProjYZ ( *it ) ) ) test++;
183  return test >= 2 ? true : false;
184 }
185 
186 /**
187  * Equality operator.
188  * @param other the object to compare with.
189  * @return 'true' either if the points perfectly match
190  * or if the first points match to the last ones
191  * (same DSS scanned in the conversed way)
192  * and 'false' otherwise
193  */
194 template <typename TIterator, typename TInteger, int connectivity>
195 inline
196 bool
197 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::operator==(
198  const Naive3DDSSComputer<TIterator,TInteger,connectivity>& other ) const
199 {
200  return ( ( ( myXYalgo == other.myXYalgo ) &&
201  ( myXZalgo == other.myXZalgo ) &&
202  ( myYZalgo == other.myYZalgo ) ) ||
203  ( (*myBegin == *other.myBegin) &&
204  (*myEnd == *other.myEnd) ) );
205 }
206 
207 /**
208  * Difference operator.
209  * @param other the object to compare with.
210  * @return 'false' if equal
211  * 'true' otherwise
212  */
213 template <typename TIterator, typename TInteger, int connectivity>
214 inline
215 bool
216 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::operator!=(
217  const Naive3DDSSComputer<TIterator,TInteger,connectivity> & other ) const
218 {
219  return (!(*this == other));
220 }
221 
222 /**
223  * Tests whether the union between a point
224  * (add to the front of the DSS
225  * with respect to the scan orientation)
226  * and a DSS is a DSS.
227  * Computes the parameters of the new DSS
228  * with the added point if true.
229  * @param it an iterator on a sequence of points
230  * @return 'true' if the union is a DSS, 'false' otherwise.
231  */
232 template <typename TIterator, typename TInteger, int connectivity>
233 inline
234 bool
235 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::extendFront()
236 {
237  if ( !isExtendableFront() ) return false;
238 
239  char test = 0;
240  if ( extendFront ( myXYalgo, blockXY ) ) test++;
241  if ( extendFront ( myXZalgo, blockXZ ) ) test++;
242  if ( extendFront ( myYZalgo, blockYZ ) ) test++;
243  if ( test >= 2 )
244  {
245  myEnd++;
246  return true;
247  }
248  else return false;
249 }
250 
251 template <typename TIterator, typename TInteger, int connectivity>
252 inline
253 bool
254 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::extendFront ( ArithmeticalDSSComputer2d & DSS2D, bool & blocked )
255 {
256  if ( DSS2D.isExtendableFront() && !blocked )
257  {
258  Point2d p = DSS2D.front();
259  DSS2D.extendFront();
260  if ( DSS2D.front() != p )
261  return true;
262  else
263  {
264  DSS2D.retractFront();
265  blocked = true;
266  return false;
267  }
268  }
269  return false;
270 }
271 
272 /** Tests whether the 3D DSS can be extended at the front.
273  *
274  * @return 'true' if yes, 'false' otherwise
275  */
276 template <typename TIterator, typename TInteger, int connectivity>
277 inline
278 bool
279 DGtal::Naive3DDSSComputer<TIterator, TInteger,connectivity>::isExtendableFront()
280 {
281  char test = 0;
282  if ( myXYalgo.isExtendableFront() && !blockXY ) test++;
283  if ( myXZalgo.isExtendableFront() && !blockXZ ) test++;
284  if ( myYZalgo.isExtendableFront() && !blockYZ ) test++;
285  if ( test >= 2 ) return true; else return false;
286 }
287 
288 template <typename TIterator, typename TInteger, int connectivity>
289 inline
290 TIterator
291 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::begin() const {
292  return myBegin;
293 }
294 
295 template <typename TIterator, typename TInteger, int connectivity>
296 inline
297 TIterator
298 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::end() const {
299  return myEnd;
300 }
301 
302 //-----------------------------------------------------------------
303 /**
304  * Checks the validity/consistency of the object.
305  * @return 'true' if the object is valid, 'false' otherwise.
306  */
307 
308 template <typename TIterator, typename TInteger, int connectivity>
309 inline
310 bool
311 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::isValid() const
312 {
313  return ( ( myXYalgo.isValid() ) &&
314  ( myXZalgo.isValid() ) &&
315  ( myYZalgo.isValid() ) );
316 }
317 
318 /**
319  * Computes the parameters
320  * (direction, intercept, thickness)
321  * of the DSS
322  * @param direction
323  * @param intercept
324  * @param thickness
325  */
326 template <typename TIterator, typename TInteger, int connectivity>
327 inline
328 void
329 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>
330 ::getParameters ( Point3d& direction, PointR3d& intercept, PointR3d& thickness ) const
331 {
332  unsigned int lenXY = std::distance ( myXYalgo.begin(), myXYalgo.end() );
333  unsigned int lenXZ = std::distance ( myXZalgo.begin(), myXZalgo.end() );
334  unsigned int lenYZ = std::distance ( myYZalgo.begin(), myYZalgo.end() );
335  if ( lenXY > lenYZ && lenXZ > lenYZ )
336  { //XY-plane, XZ-plane
337 
338  Integer a1 = myXYalgo.b();
339  Integer b1 = myXYalgo.a();
340  Integer a2 = myXZalgo.b();
341  Integer c1 = myXZalgo.a();
342 
343  if ( c1 == 0 || ( a1 == 0 && a2 == 0 ) )
344  direction = Point3d ( a1, b1, c1 );
345  else
346  {
347  if ( b1 == 0 )
348  direction = Point3d ( a2, b1, c1 );
349  else
350  {
351  direction = Point3d ( a1 * a2 , a2 * b1 , a1 * c1 );
352  }
353  }
354 
355  Integer mu1 = myXYalgo.mu();
356  Integer mu2 = myXZalgo.mu();
357  intercept[0] = std::make_pair ( 0, 1 ); intercept[1] = std::make_pair ( -mu1, a1 ); intercept[2] = std::make_pair ( -mu2, a2 );
358 
359  Integer omega1 = myXYalgo.omega()-1;
360  Integer omega2 = myXZalgo.omega()-1;
361  thickness[0] = std::make_pair ( 0, 1 ); thickness[1] = std::make_pair ( -omega1, a1 ); thickness[2] = std::make_pair ( -omega2, a2 );
362 
363  }
364  else
365  {
366  if ( lenYZ > lenXZ && lenXY > lenXZ )
367  { //XY-plane, YZ-plane
368 
369  Integer a1 = myXYalgo.b();
370  Integer b1 = myXYalgo.a();
371  Integer b2 = myYZalgo.b();
372  Integer c2 = myYZalgo.a();
373 
374  if ( a1 == 0 || ( b2 == 0 && b1 == 0 ) )
375  direction = Point3d ( a1, b2, c2 );
376  else
377  {
378  if ( c2 == 0 )
379  direction = Point3d ( a1, b1, c2 );
380  else
381  {
382  direction = Point3d ( b2 * a1 , b1 * b2 , b1 * c2 );
383  }
384  }
385 
386  Integer mu1 = myXYalgo.mu();
387  Integer mu2 = myYZalgo.mu();
388  intercept[0] = std::make_pair ( mu1, b1 ); intercept[1] = std::make_pair ( 0, 1 ); intercept[2] = std::make_pair ( -mu2, b2 );
389 
390  Integer omega1 = myXYalgo.omega()-1;
391  Integer omega2 = myYZalgo.omega()-1;
392  thickness[0] = std::make_pair ( omega1, b1 ); thickness[1] = std::make_pair ( 0, 1 ); thickness[2] = std::make_pair ( -omega2, b2 );
393 
394  }
395  else
396  { //YZ-plane, XZ-plane
397  Integer b2 = myYZalgo.b();
398  Integer c2 = myYZalgo.a();
399  Integer a2 = myXZalgo.b();
400  Integer c1 = myXZalgo.a();
401 
402  if ( a2 == 0 || ( c2 == 0 && c1 == 0 ) )
403  direction = Point3d ( a2, b2, c2 );
404  else
405  {
406  if ( b2 == 0 )
407  direction = Point3d ( a2, b2, c1 );
408  else
409  {
410  direction = Point3d ( c2 * a2, c1 * b2, c1 * c2 );
411  }
412  }
413 
414  Integer mu1 = myYZalgo.mu();
415  Integer mu2 = myXZalgo.mu();
416  intercept[0] = std::make_pair ( mu2, c1 ); intercept[1] = std::make_pair ( mu1, c2 ); intercept[2] = std::make_pair ( 0, 1 );
417 
418  Integer omega1 = myYZalgo.omega()-1;
419  Integer omega2 = myXZalgo.omega()-1;
420  thickness[0] = std::make_pair ( omega2, c1 ); thickness[1] = std::make_pair ( omega1, c2 ); thickness[2] = std::make_pair ( 0, 1);
421  }
422  }
423 }
424 
425 //-----------------------------------------------------------------------------
426 template <typename TIterator, typename TInteger, int connectivity>
427 inline
428 const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
429 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXY() const
430 {
431  return myXYalgo;
432 }
433 //-----------------------------------------------------------------------------
434 template <typename TIterator, typename TInteger, int connectivity>
435 inline
436 const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
437 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXZ() const
438 {
439  return myXZalgo;
440 }
441 //-----------------------------------------------------------------------------
442 template <typename TIterator, typename TInteger, int connectivity>
443 inline
444 const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
445 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2dYZ() const
446 {
447  return myYZalgo;
448 }
449 //-----------------------------------------------------------------------------
450 template <typename TIterator, typename TInteger, int connectivity>
451 inline
452 const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
453 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2d( Dimension i ) const
454 {
455  ASSERT( i < 3 );
456  switch ( i ) {
457  case 0: return myYZalgo; break;
458  case 1: return myXZalgo; break;
459  default: return myXYalgo; break;
460  }
461 }
462 
463 template <typename TIterator, typename TInteger, int connectivity>
464 inline
465 bool
466 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::validArithmeticalDSS2d( Dimension i ) const
467 {
468  ASSERT( i < 3 );
469  unsigned int lenXY = std::distance ( myXYalgo.begin(), myXYalgo.end() );
470  unsigned int lenXZ = std::distance ( myXZalgo.begin(), myXZalgo.end() );
471  unsigned int lenYZ = std::distance ( myYZalgo.begin(), myYZalgo.end() );
472  if ( i == 0 && ( lenYZ >= lenXZ || lenYZ >= lenXY ) )
473  return true;
474  else if ( i == 1 && ( lenXZ >= lenXY || lenXZ >= lenYZ ) )
475  return true;
476  else if ( i == 2 && ( lenXY >= lenXZ || lenXY >= lenYZ ) )
477  return true;
478  return false;
479 }
480 
481 /**
482  * @return the style name used for drawing this object.
483  */
484 template <typename TIterator, typename TInteger, int connectivity>
485 inline
486 std::string
487 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::className() const
488 {
489  return "Naive3DDSSComputer";
490 }
491 
492 
493 ///////////////////////////////////////////////////////////////////////////////
494 // Implementation of inline functions and external operators //
495 
496 //------------------------------------------------------------------------------
497 // TEXT DISPLAY
498 
499 /**
500  * Writes/Displays the object on an output stream.
501  * @param out the output stream where the object is written.
502  */
503 template <typename TIterator, typename TInteger, int connectivity>
504 inline
505 void
506 DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::selfDisplay ( std::ostream & out)
507 {
508  out << "[Naive3DDSSComputer] " << " [XYprojection] " << myXYalgo << " [XZprojection] ";
509  out << myXZalgo << " [YZprojection] " << myYZalgo << " [End Naive3DDSSComputer]" << std::endl;
510 }
511 // //
512 ///////////////////////////////////////////////////////////////////////////////
513 
514