DGtal 2.1.0
Loading...
Searching...
No Matches
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 */
40template <typename TIterator, typename TInteger, int connectivity>
41inline
42DGtal::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 */
61template <typename TIterator, typename TInteger, int connectivity>
62inline
63DGtal::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 */
84template <typename TIterator, typename TInteger, int connectivity>
85inline
86void 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 */
107template <typename TIterator, typename TInteger, int connectivity>
108inline
109DGtal::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 */
126template <typename TIterator, typename TInteger, int connectivity>
127inline
128DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity> &
129DGtal::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
146template <typename TIterator, typename TInteger, int connectivity>
147inline
148typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Self
149DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::getSelf() const
150{
151 return Self();
152}
153
154template <typename TIterator, typename TInteger, int connectivity>
155inline
156typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::Reverse
157DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::getReverse() const
158{
159 return Reverse();
160}
161
162template <typename TIterator, typename TInteger, int connectivity>
163inline
164bool
165DGtal::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
174template <typename TIterator, typename TInteger, int connectivity>
175inline
176bool
177DGtal::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 */
194template <typename TIterator, typename TInteger, int connectivity>
195inline
196bool
197DGtal::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 */
213template <typename TIterator, typename TInteger, int connectivity>
214inline
215bool
216DGtal::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 * @return 'true' if the union is a DSS, 'false' otherwise.
230 */
231template <typename TIterator, typename TInteger, int connectivity>
232inline
233bool
234DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::extendFront()
235{
236 if ( !isExtendableFront() ) return false;
237
238 char test = 0;
239 if ( extendFront ( myXYalgo, blockXY ) ) test++;
240 if ( extendFront ( myXZalgo, blockXZ ) ) test++;
241 if ( extendFront ( myYZalgo, blockYZ ) ) test++;
242 if ( test >= 2 )
243 {
244 myEnd++;
245 return true;
246 }
247
248 /**
249 * Ensure that the last segment is maximal in 2D,
250 * so that the corresponding 3D segment results from
251 * the intersection of two maximal 2D segments.
252 */
253 while (extendFront ( myXYalgo, blockXY ) );;
254 while (extendFront ( myXZalgo, blockXZ ) );;
255 while (extendFront ( myYZalgo, blockYZ ) );;
256
257 return test == 1;
258}
259
260template <typename TIterator, typename TInteger, int connectivity>
261inline
262bool
263DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::extendFront ( ArithmeticalDSSComputer2d & DSS2D, bool & blocked )
264{
265 if ( DSS2D.isExtendableFront() && !blocked )
266 {
267 Point2d p = DSS2D.front();
268 DSS2D.extendFront();
269 if ( DSS2D.front() != p )
270 return true;
271 else
272 {
273 DSS2D.retractFront();
274 blocked = true;
275 return false;
276 }
277 }
278 return false;
279}
280
281/** Tests whether the 3D DSS can be extended at the front.
282 *
283 * @return 'true' if yes, 'false' otherwise
284 */
285template <typename TIterator, typename TInteger, int connectivity>
286inline
287bool
288DGtal::Naive3DDSSComputer<TIterator, TInteger,connectivity>::isExtendableFront()
289{
290 char test = 0;
291 if ( myXYalgo.isExtendableFront() && !blockXY ) test++;
292 if ( myXZalgo.isExtendableFront() && !blockXZ ) test++;
293 if ( myYZalgo.isExtendableFront() && !blockYZ ) test++;
294 return test >= 2;
295}
296
297template <typename TIterator, typename TInteger, int connectivity>
298inline
299TIterator
300DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::begin() const {
301 return myBegin;
302}
303
304template <typename TIterator, typename TInteger, int connectivity>
305inline
306TIterator
307DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::end() const {
308 return myEnd;
309}
310
311//-----------------------------------------------------------------
312/**
313 * Checks the validity/consistency of the object.
314 * @return 'true' if the object is valid, 'false' otherwise.
315 */
316
317template <typename TIterator, typename TInteger, int connectivity>
318inline
319bool
320DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::isValid() const
321{
322 return ( ( myXYalgo.isValid() ) &&
323 ( myXZalgo.isValid() ) &&
324 ( myYZalgo.isValid() ) );
325}
326
327/**
328 * Computes the parameters
329 * (direction, intercept, thickness)
330 * of the DSS
331 */
332template <typename TIterator, typename TInteger, int connectivity>
333inline
334void
335DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>
336::getParameters ( Point3d& direction, PointR3d& intercept, PointR3d& thickness ) const
337{
338 auto lenXY = std::distance ( myXYalgo.begin(), myXYalgo.end() );
339 auto lenXZ = std::distance ( myXZalgo.begin(), myXZalgo.end() );
340 auto lenYZ = std::distance ( myYZalgo.begin(), myYZalgo.end() );
341 if ( lenXY > lenYZ && lenXZ > lenYZ )
342 { //XY-plane, XZ-plane
343
344 Integer a1 = myXYalgo.b();
345 Integer b1 = myXYalgo.a();
346 Integer a2 = myXZalgo.b();
347 Integer c1 = myXZalgo.a();
348
349 if ( c1 == 0 || ( a1 == 0 && a2 == 0 ) )
350 direction = Point3d ( a1, b1, c1 );
351 else
352 {
353 if ( b1 == 0 )
354 direction = Point3d ( a2, b1, c1 );
355 else
356 {
357 direction = Point3d ( a1 * a2 , a2 * b1 , a1 * c1 );
358 }
359 }
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 }
370 else
371 {
372 if ( lenYZ > lenXZ && lenXY > lenXZ )
373 { //XY-plane, YZ-plane
374
375 Integer a1 = myXYalgo.b();
376 Integer b1 = myXYalgo.a();
377 Integer b2 = myYZalgo.b();
378 Integer c2 = myYZalgo.a();
379
380 if ( a1 == 0 || ( b2 == 0 && b1 == 0 ) )
381 direction = Point3d ( a1, b2, c2 );
382 else
383 {
384 if ( c2 == 0 )
385 direction = Point3d ( a1, b1, c2 );
386 else
387 {
388 direction = Point3d ( b2 * a1 , b1 * b2 , b1 * c2 );
389 }
390 }
391
392 Integer mu1 = myXYalgo.mu();
393 Integer mu2 = myYZalgo.mu();
394 intercept[0] = std::make_pair ( mu1, b1 ); intercept[1] = std::make_pair ( 0, 1 ); intercept[2] = std::make_pair ( -mu2, b2 );
395
396 Integer omega1 = myXYalgo.omega()-1;
397 Integer omega2 = myYZalgo.omega()-1;
398 thickness[0] = std::make_pair ( omega1, b1 ); thickness[1] = std::make_pair ( 0, 1 ); thickness[2] = std::make_pair ( -omega2, b2 );
399
400 }
401 else
402 { //YZ-plane, XZ-plane
403 Integer b2 = myYZalgo.b();
404 Integer c2 = myYZalgo.a();
405 Integer a2 = myXZalgo.b();
406 Integer c1 = myXZalgo.a();
407
408 if ( a2 == 0 || ( c2 == 0 && c1 == 0 ) )
409 direction = Point3d ( a2, b2, c2 );
410 else
411 {
412 if ( b2 == 0 )
413 direction = Point3d ( a2, b2, c1 );
414 else
415 {
416 direction = Point3d ( c2 * a2, c1 * b2, c1 * c2 );
417 }
418 }
419
420 Integer mu1 = myYZalgo.mu();
421 Integer mu2 = myXZalgo.mu();
422 intercept[0] = std::make_pair ( mu2, c1 ); intercept[1] = std::make_pair ( mu1, c2 ); intercept[2] = std::make_pair ( 0, 1 );
423
424 Integer omega1 = myYZalgo.omega()-1;
425 Integer omega2 = myXZalgo.omega()-1;
426 thickness[0] = std::make_pair ( omega2, c1 ); thickness[1] = std::make_pair ( omega1, c2 ); thickness[2] = std::make_pair ( 0, 1);
427 }
428 }
429}
430
431//-----------------------------------------------------------------------------
432template <typename TIterator, typename TInteger, int connectivity>
433inline
434const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
435DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXY() const
436{
437 return myXYalgo;
438}
439//-----------------------------------------------------------------------------
440template <typename TIterator, typename TInteger, int connectivity>
441inline
442const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
443DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2dXZ() const
444{
445 return myXZalgo;
446}
447//-----------------------------------------------------------------------------
448template <typename TIterator, typename TInteger, int connectivity>
449inline
450const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
451DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2dYZ() const
452{
453 return myYZalgo;
454}
455//-----------------------------------------------------------------------------
456template <typename TIterator, typename TInteger, int connectivity>
457inline
458const typename DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::ArithmeticalDSSComputer2d &
459DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::arithmeticalDSS2d( Dimension i ) const
460{
461 ASSERT( i < 3 );
462 switch ( i ) {
463 case 0: return myYZalgo; break;
464 case 1: return myXZalgo; break;
465 default: return myXYalgo; break;
466 }
467}
468
469template <typename TIterator, typename TInteger, int connectivity>
470inline
471bool
472DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::validArithmeticalDSS2d( Dimension i ) const
473{
474 ASSERT( i < 3 );
475 auto lenXY = std::distance ( myXYalgo.begin(), myXYalgo.end() );
476 auto lenXZ = std::distance ( myXZalgo.begin(), myXZalgo.end() );
477 auto lenYZ = std::distance ( myYZalgo.begin(), myYZalgo.end() );
478 if ( i == 0 && ( lenYZ >= lenXZ || lenYZ >= lenXY ) )
479 return true;
480 else if ( i == 1 && ( lenXZ >= lenXY || lenXZ >= lenYZ ) )
481 return true;
482 else if ( i == 2 && ( lenXY >= lenXZ || lenXY >= lenYZ ) )
483 return true;
484 return false;
485}
486
487/**
488 * @return the style name used for drawing this object.
489 */
490template <typename TIterator, typename TInteger, int connectivity>
491inline
492std::string
493DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::className() const
494{
495 return "Naive3DDSSComputer";
496}
497
498
499///////////////////////////////////////////////////////////////////////////////
500// Implementation of inline functions and external operators //
501
502//------------------------------------------------------------------------------
503// TEXT DISPLAY
504
505/**
506 * Writes/Displays the object on an output stream.
507 * @param out the output stream where the object is written.
508 */
509template <typename TIterator, typename TInteger, int connectivity>
510inline
511void
512DGtal::Naive3DDSSComputer<TIterator,TInteger,connectivity>::selfDisplay ( std::ostream & out)
513{
514 out << "[Naive3DDSSComputer] " << " [XYprojection] " << myXYalgo << " [XZprojection] ";
515 out << myXZalgo << " [YZprojection] " << myYZalgo << " [End Naive3DDSSComputer]" << std::endl;
516}
517// //
518///////////////////////////////////////////////////////////////////////////////
519
520