DGtal  1.0.0
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  * @param it an iterator on a sequence of points
252  * @return 'true' if the union is a DSS, 'false' otherwise.
253  */
254 template <typename TIterator, typename TInteger, int connectivity>
255 inline
256 bool
257 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::extendFront()
258 {
259  if( isExtendableFront() ) {
260 
261  bool XYflag = myXYalgo.extendFront();
262  bool XZflag = myXZalgo.extendFront();
263  bool YZflag = myYZalgo.extendFront();
264  ASSERT( (XYflag)&&(XZflag)&&(YZflag) );
265  boost::ignore_unused_variable_warning(XYflag);
266  boost::ignore_unused_variable_warning(XZflag);
267  boost::ignore_unused_variable_warning(YZflag);
268 
269  myEnd++;
270  return true;
271  } else return false;
272 }
273 
274 
275 
276 /** Tests whether the 3d DSS can be extended at the front.
277  *
278  * @return 'true' if yes, 'false' otherwise
279  */
280 template <typename TIterator, typename TInteger, int connectivity>
281 inline
282 bool
283 DGtal::StandardDSS6Computer<TIterator, TInteger,connectivity>::isExtendableFront()
284 {
285  //projection on xy-plane
286  bool XYflag = myXYalgo.isExtendableFront();
287 
288  //projection on xz-plane
289  bool XZflag = myXZalgo.isExtendableFront();
290 
291  //projection on yz-plane
292  bool YZflag = myYZalgo.isExtendableFront();
293 
294  return (XYflag && XZflag && YZflag);
295 }
296 
297 
298 
299 
300 template <typename TIterator, typename TInteger, int connectivity>
301 inline
302 TIterator
303 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::begin() const {
304  return myBegin;
305 }
306 
307 template <typename TIterator, typename TInteger, int connectivity>
308 inline
309 TIterator
310 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::end() const {
311  return myEnd;
312 }
313 
314 
315 
316 
317 //-----------------------------------------------------------------
318 /**
319  * Checks the validity/consistency of the object.
320  * @return 'true' if the object is valid, 'false' otherwise.
321  */
322 
323 template <typename TIterator, typename TInteger, int connectivity>
324 inline
325 bool
326 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::isValid() const
327 {
328  return ( (myXYalgo.isValid())&&
329  (myXZalgo.isValid())&&
330  (myYZalgo.isValid()) );
331 }
332 
333 
334 /**
335  * Computes the parameters
336  * (direction, intercept, thickness)
337  * of the DSS
338  * @param direction
339  * @param intercept
340  * @param thickness
341  */
342 template <typename TIterator, typename TInteger, int connectivity>
343 inline
344 void
345 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>
346 ::getParameters ( Point3d& direction, PointR3d& intercept, PointR3d& thickness ) const
347 {
348 
349  //let us take the pair of projection planes for which
350  //the common coordinate of the main vector cannot be 0
351 
352  if (myXYalgo.b() != 0) { //XY-plane, XZ-plane
353 
354  Integer a1 = myXYalgo.b();
355  Integer b1 = myXYalgo.a();
356  Integer a2 = myXZalgo.b();
357  Integer c1 = myXZalgo.a();
358 
359  direction = Point3d(a1*a2,a2*b1,a1*c1);
360 
361  Integer mu1 = myXYalgo.mu();
362  Integer mu2 = myXZalgo.mu();
363  intercept[0] = std::make_pair ( 0, 1 ); intercept[1] = std::make_pair ( -mu1, a1 ); intercept[2] = std::make_pair ( -mu2, a2 );
364 
365  Integer omega1 = myXYalgo.omega()-1;
366  Integer omega2 = myXZalgo.omega()-1;
367  thickness[0] = std::make_pair ( 0, 1 ); thickness[1] = std::make_pair ( -omega1, a1 ); thickness[2] = std::make_pair ( -omega2, a2 );
368 
369  } else {
370 
371  if (myXYalgo.a() != 0) {//XY-plane, YZ-plane
372 
373  Integer a1 = myXYalgo.b();
374  Integer b1 = myXYalgo.a();
375  Integer b2 = myYZalgo.b();
376  Integer c2 = myYZalgo.a();
377 
378  direction = Point3d(b2*a1,b1*b2,b1*c2);
379 
380  Integer mu1 = myXYalgo.mu();
381  Integer mu2 = myYZalgo.mu();
382  intercept[0] = std::make_pair ( mu1, b1 ); intercept[1] = std::make_pair ( 0, 1 ); intercept[2] = std::make_pair ( -mu2, b2 );
383 
384  Integer omega1 = myXYalgo.omega()-1;
385  Integer omega2 = myYZalgo.omega()-1;
386  thickness[0] = std::make_pair ( omega1, b1 ); thickness[1] = std::make_pair ( 0, 1 ); thickness[2] = std::make_pair ( -omega2, b2 );
387 
388  } else {
389 
390  if (myYZalgo.a() != 0) {//YZ-plane, XZ-plane
391 
392  std::cerr << "YZ-XZ" << std::endl;
393 
394  Integer b2 = myYZalgo.b();
395  Integer c2 = myYZalgo.a();
396  Integer a2 = myXZalgo.b();
397  Integer c1 = myXZalgo.a();
398 
399  direction = Point3d(c2*a2,c1*b2,c1*c2);
400 
401  Integer mu1 = myYZalgo.mu();
402  Integer mu2 = myXZalgo.mu();
403  intercept[0] = std::make_pair ( mu2, c1 ); intercept[1] = std::make_pair ( mu1, c2 ); intercept[2] = std::make_pair ( 0, 1 );
404 
405  Integer omega1 = myYZalgo.omega()-1;
406  Integer omega2 = myXZalgo.omega()-1;
407  thickness[0] = std::make_pair ( omega2, c1 ); thickness[1] = std::make_pair ( omega1, c2 ); thickness[2] = std::make_pair ( 0, 1);
408 
409  } else {//degenerated case
410  direction = Point3d(0,0,0);
411  intercept[0] = std::make_pair ( 0, 1 ); intercept[1] = std::make_pair ( 0, 1 ); intercept[2] = std::make_pair ( 0, 1 );
412  thickness[0] = std::make_pair ( 0, 1 ); thickness[1] = std::make_pair ( 0, 1 ); thickness[2] = std::make_pair ( 0, 1);
413  }
414  }
415  }
416 
417 }
418 
419 //-----------------------------------------------------------------------------
420 template <typename TIterator, typename TInteger, int connectivity>
421 inline
422 const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
423 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXY() const
424 {
425  return myXYalgo;
426 }
427 //-----------------------------------------------------------------------------
428 template <typename TIterator, typename TInteger, int connectivity>
429 inline
430 const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
431 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXZ() const
432 {
433  return myXZalgo;
434 }
435 //-----------------------------------------------------------------------------
436 template <typename TIterator, typename TInteger, int connectivity>
437 inline
438 const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
439 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2dYZ() const
440 {
441  return myYZalgo;
442 }
443 //-----------------------------------------------------------------------------
444 template <typename TIterator, typename TInteger, int connectivity>
445 inline
446 const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
447 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2d( Dimension i ) const
448 {
449  ASSERT( ( 0 <= i ) && ( i < 3 ) );
450  switch ( i ) {
451  case 0: return myYZalgo; break;
452  case 1: return myXZalgo; break;
453  default: return myXYalgo; break;
454  }
455 }
456 
457 
458 /**
459  * @return the style name used for drawing this object.
460  */
461 template <typename TIterator, typename TInteger, int connectivity>
462 inline
463 std::string
464 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::className() const
465 {
466  return "StandardDSS6Computer";
467 }
468 
469 //------------------------------------------------------------------------------
470 // TEXT DISPLAY
471 
472 /**
473  * Writes/Displays the object on an output stream.
474  * @param out the output stream where the object is written.
475  */
476 template <typename TIterator, typename TInteger, int connectivity>
477 inline
478 void
479 DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::selfDisplay ( std::ostream & out) const
480 {
481 
482  out << "[StandardDSS6Computer]" << std::endl;
483  out << "[XYprojection]" << std::endl;
484  out << myXYalgo << std::endl;
485  out << "[XZprojection]" << std::endl;
486  out << myXZalgo << std::endl;
487  out << "[YZprojection]" << std::endl;
488  out << myYZalgo << std::endl;
489  out << "[End StandardDSS6Computer]" << std::endl;
490 
491 }
492 
493 
494 //------------------------------------------------------------------------------
495 // 3D DRAWING