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