DGtal 1.4.0
Loading...
Searching...
No Matches
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 */
55template <typename TIterator, typename TInteger, int connectivity>
56inline
57DGtal::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 */
78template <typename TIterator, typename TInteger, int connectivity>
79inline
80DGtal::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 */
102template <typename TIterator, typename TInteger, int connectivity>
103inline
104void 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 */
130template <typename TIterator, typename TInteger, int connectivity>
131inline
132DGtal::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 */
145template <typename TIterator, typename TInteger, int connectivity>
146inline
147DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity> &
148DGtal::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
164template <typename TIterator, typename TInteger, int connectivity>
165inline
166typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::Self
167DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::getSelf() const {
168 return Self();
169}
170
171
172template <typename TIterator, typename TInteger, int connectivity>
173inline
174typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::Reverse
175DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::getReverse() const {
176 return Reverse();
177}
178
179template <typename TIterator, typename TInteger, int connectivity>
180inline
181bool
182DGtal::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
192template <typename TIterator, typename TInteger, int connectivity>
193inline
194bool
195DGtal::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 */
213template <typename TIterator, typename TInteger, int connectivity>
214inline
215bool
216DGtal::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 */
232template <typename TIterator, typename TInteger, int connectivity>
233inline
234bool
235DGtal::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 */
253template <typename TIterator, typename TInteger, int connectivity>
254inline
255bool
256DGtal::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 */
279template <typename TIterator, typename TInteger, int connectivity>
280inline
281bool
282DGtal::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
299template <typename TIterator, typename TInteger, int connectivity>
300inline
301TIterator
302DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::begin() const {
303 return myBegin;
304}
305
306template <typename TIterator, typename TInteger, int connectivity>
307inline
308TIterator
309DGtal::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
322template <typename TIterator, typename TInteger, int connectivity>
323inline
324bool
325DGtal::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 */
338template <typename TIterator, typename TInteger, int connectivity>
339inline
340void
341DGtal::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//-----------------------------------------------------------------------------
416template <typename TIterator, typename TInteger, int connectivity>
417inline
418const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
419DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXY() const
420{
421 return myXYalgo;
422}
423//-----------------------------------------------------------------------------
424template <typename TIterator, typename TInteger, int connectivity>
425inline
426const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
427DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXZ() const
428{
429 return myXZalgo;
430}
431//-----------------------------------------------------------------------------
432template <typename TIterator, typename TInteger, int connectivity>
433inline
434const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
435DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::arithmeticalDSS2dYZ() const
436{
437 return myYZalgo;
438}
439//-----------------------------------------------------------------------------
440template <typename TIterator, typename TInteger, int connectivity>
441inline
442const typename DGtal::StandardDSS6Computer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
443DGtal::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 */
457template <typename TIterator, typename TInteger, int connectivity>
458inline
459std::string
460DGtal::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 */
472template <typename TIterator, typename TInteger, int connectivity>
473inline
474void
475DGtal::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