DGtal  1.5.beta
ArithmeticalDSSComputerOnSurfels.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 ArithmeticalDSSComputerOnSurfels.ih
19  * @author Jocelyn Meyron (\c jocelyn.meyron@liris.cnrs.fr )
20  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21  * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
22  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
23  *
24  * @date 2021/01/22
25  *
26  * Implementation of inline methods defined in ArithmeticalDSSComputerOnSurfels.h
27  *
28  * This file is part of the DGtal library.
29  */
30 
31 ///////////////////////////////////////////////////////////////////////////////
32 // IMPLEMENTATION of inline methods.
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 //////////////////////////////////////////////////////////////////////////////
36 #include <cstdlib>
37 #include <algorithm>
38 #include <boost/version.hpp>
39 #if BOOST_VERSION < 105800
40 #include <boost/math/common_factor_rt.hpp>
41 #else
42 #include <boost/integer/common_factor_rt.hpp>
43 #endif
44 
45 //////////////////////////////////////////////////////////////////////////////
46 
47 
48 ///////////////////////////////////////////////////////////////////////////////
49 // Implementation of inline methods //
50 
51 //-----------------------------------------------------------------------------
52 template <typename TKSpace, typename TIterator, typename TInteger>
53 inline
54 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
55 ArithmeticalDSSComputerOnSurfels()
56  : myKSpace(nullptr), mySliceAxis1(), mySliceAxis2(), myProjectionAxis(),
57  my2DProjector(), myExtractor(nullptr), myDSS( Point(0,0) ), myBegin(), myEnd()
58 {
59 }
60 
61 //-----------------------------------------------------------------------------
62 template <typename TKSpace, typename TIterator, typename TInteger>
63 inline
64 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
65 ArithmeticalDSSComputerOnSurfels(const KSpace& aKSpace, Dimension aDim1, Dimension aDim2, bool aFlagToReverse)
66  : myKSpace(&aKSpace), mySliceAxis1(aDim1), mySliceAxis2(aDim2), myProjectionAxis(),
67  my2DProjector(), myExtractor(), myDSS( Point(0,0) ), myBegin(), myEnd()
68 {
69  ASSERT(aDim1 != aDim2);
70 
71  myProjectionAxis = dimNotIn(aDim1, aDim2);
72 
73  std::vector<Dimension> v = {aDim1, aDim2};
74  my2DProjector.init(v.begin(),v.end());
75 
76  if (aFlagToReverse) {
77  myExtractor = PairExtractor(new IndirectPairExtractor());
78  } else {
79  myExtractor = PairExtractor(new DirectPairExtractor());
80  }
81 }
82 
83 //-----------------------------------------------------------------------------
84 template <typename TKSpace, typename TIterator, typename TInteger>
85 inline
86 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
87 ArithmeticalDSSComputerOnSurfels ( const ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger> & other )
88  : myKSpace(other.myKSpace), mySliceAxis1(other.mySliceAxis1), mySliceAxis2(other.mySliceAxis2), myProjectionAxis(other.myProjectionAxis),
89  my2DProjector(other.my2DProjector), myExtractor(other.myExtractor), myDSS(other.myDSS), myBegin(other.myBegin), myEnd(other.myEnd)
90 {
91 }
92 
93 //-----------------------------------------------------------------------------
94 template <typename TKSpace, typename TIterator, typename TInteger>
95 inline
96 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>&
97 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
98 operator=( const ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger> & other )
99 {
100  if ( this != &other )
101  {
102  myKSpace = other.myKSpace;
103  mySliceAxis1 = other.mySliceAxis1;
104  mySliceAxis2 = other.mySliceAxis2;
105  myProjectionAxis = other.myProjectionAxis;
106  my2DProjector = other.my2DProjector;
107  myExtractor = other.myExtractor;
108  myDSS = other.myDSS;
109  myBegin = other.myBegin;
110  myEnd = other.myEnd;
111  }
112  return *this;
113 }
114 
115 //-----------------------------------------------------------------------------
116 template <typename TKSpace, typename TIterator, typename TInteger>
117 inline
118 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Reverse
119 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>
120 ::getReverse() const
121 {
122  return Reverse(*myKSpace, mySliceAxis1, mySliceAxis2, true);
123 }
124 
125 //-----------------------------------------------------------------------------
126 template <typename TKSpace, typename TIterator, typename TInteger>
127 inline
128 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Self
129 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>
130 ::getSelf() const
131 {
132  return Self(*myKSpace, mySliceAxis1, mySliceAxis2);
133 }
134 
135 //-----------------------------------------------------------------------------
136 template <typename TKSpace, typename TIterator, typename TInteger>
137 inline
138 bool
139 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
140 operator==( const ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>& other ) const
141 {
142  return ( (myBegin == other.myBegin)
143  && (myEnd == other.myEnd)
144  && (myDSS == other.myDSS) );
145 }
146 
147 //-----------------------------------------------------------------------------
148 template <typename TKSpace, typename TIterator, typename TInteger>
149 inline
150 bool
151 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
152 operator!=( const ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger> & other ) const
153 {
154  return (!(*this == other));
155 }
156 
157 ///////////////////////////////////////////////////////////////////////////////
158 // Update methods //
159 ///////////////////////////////////////////////////////////////////////////////
160 //--------------------------------------------------------------------
161 template <typename TKSpace, typename TIterator, typename TInteger>
162 inline
163 bool
164 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::isExtendableFront()
165 {
166  //the caller must be sure that 'myEnd' can be safely dereferenced
167  return myDSS.isExtendableFront( getNextProjectedPoint(*myEnd) );
168 }
169 
170 //--------------------------------------------------------------------
171 template <typename TKSpace, typename TIterator, typename TInteger>
172 inline
173 bool
174 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::isExtendableBack()
175 {
176  ConstIterator it = myBegin;
177  --it;
178  //the caller must be sure that 'it' can be safely dereferenced
179  return myDSS.isExtendableBack( getPreviousProjectedPoint(*it) );
180 }
181 
182 //-----------------------------------------------------------------------------
183 template <typename TKSpace, typename TIterator, typename TInteger>
184 inline
185 bool
186 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::extendFront()
187 {
188  //the caller must be sure that 'myEnd' can be safely dereferenced
189  if (myDSS.extendFront(getNextProjectedPoint(*myEnd)))
190  {
191  ++myEnd;
192  return true;
193  }
194  else
195  return false;
196 }
197 
198 //--------------------------------------------------------------------
199 template <typename TKSpace, typename TIterator, typename TInteger>
200 inline
201 bool
202 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::extendBack()
203 {
204  ConstIterator it = myBegin;
205  --it;
206  //the caller must be sure that 'it' can be safely dereferenced
207  if (myDSS.extendBack(getPreviousProjectedPoint(*it)))
208  {
209  myBegin = it;
210  return true;
211  }
212  else
213  return false;
214 }
215 
216 //--------------------------------------------------------------------
217 template <typename TKSpace, typename TIterator, typename TInteger>
218 inline
219 bool
220 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::retractFront()
221 {
222  if (myDSS.retractFront())
223  {
224  --myEnd;
225  return true;
226  }
227  else
228  return false;
229 }
230 
231 //--------------------------------------------------------------------
232 template <typename TKSpace, typename TIterator, typename TInteger>
233 inline
234 bool
235 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::retractBack()
236 {
237  if (myDSS.retractBack())
238  {
239  ++myBegin;
240  return true;
241  }
242  else
243  return false;
244 }
245 
246 ///////////////////////////////////////////////////////////////////////////////
247 // Accessors //
248 ///////////////////////////////////////////////////////////////////////////////
249 //-------------------------------------------------------------------------
250 template <typename TKSpace, typename TIterator, typename TInteger>
251 inline
252 const typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Primitive&
253 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::primitive() const
254 {
255  return myDSS;
256 }
257 
258 //-------------------------------------------------------------------------
259 template <typename TKSpace, typename TIterator, typename TInteger>
260 inline
261 TInteger
262 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::a() const
263 {
264  return myDSS.a();
265 }
266 
267 //-------------------------------------------------------------------------
268 template <typename TKSpace, typename TIterator, typename TInteger>
269 inline
270 TInteger
271 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::b() const
272 {
273  return myDSS.b();
274 }
275 
276 //-------------------------------------------------------------------------
277 template <typename TKSpace, typename TIterator, typename TInteger>
278 inline
279 TInteger
280 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::mu() const
281 {
282  return myDSS.mu();
283 }
284 
285 //-------------------------------------------------------------------------
286 template <typename TKSpace, typename TIterator, typename TInteger>
287 inline
288 TInteger
289 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::omega() const
290 {
291  return myDSS.omega();
292 }
293 
294 //-------------------------------------------------------------------------
295 template <typename TKSpace, typename TIterator, typename TInteger>
296 inline
297 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
298 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Uf() const
299 {
300  return myDSS.Uf();
301 }
302 
303 //-------------------------------------------------------------------------
304 template <typename TKSpace, typename TIterator, typename TInteger>
305 inline
306 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
307 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Ul() const
308 {
309  return myDSS.Ul();
310 }
311 
312 //-------------------------------------------------------------------------
313 template <typename TKSpace, typename TIterator, typename TInteger>
314 inline
315 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
316 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Lf() const
317 {
318  return myDSS.Lf();
319 }
320 
321 //-------------------------------------------------------------------------
322 template <typename TKSpace, typename TIterator, typename TInteger>
323 inline
324 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
325 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Ll() const
326 {
327  return myDSS.Ll();
328 }
329 
330 //-------------------------------------------------------------------------
331 template <typename TKSpace, typename TIterator, typename TInteger>
332 inline
333 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
334 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::back() const
335 {
336  return myDSS.back();
337 }
338 
339 //-------------------------------------------------------------------------
340 template <typename TKSpace, typename TIterator, typename TInteger>
341 inline
342 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
343 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::front() const
344 {
345  return myDSS.front();
346 }
347 
348 //-------------------------------------------------------------------------
349 template <typename TKSpace, typename TIterator, typename TInteger>
350 inline
351 TIterator
352 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::begin() const
353 {
354  return myBegin;
355 }
356 
357 //-------------------------------------------------------------------------
358 template <typename TKSpace, typename TIterator, typename TInteger>
359 inline
360 TIterator
361 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::end() const
362 {
363  return myEnd;
364 }
365 
366 //-----------------------------------------------------------------
367 template <typename TKSpace, typename TIterator, typename TInteger>
368 inline
369 bool
370 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::isValid() const
371 {
372  return ( (myDSS.isValid())&&(isNotEmpty(myBegin,myEnd)) );
373 }
374 
375 //-----------------------------------------------------------------
376 template <typename TKSpace, typename TIterator, typename TInteger>
377 inline
378 void
379 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::selfDisplay ( std::ostream & out) const
380 {
381  out << "[ArithmeticalDSSComputerOnSurfels] " << myDSS;
382 }
383 
384 ///////////////////////////////////////////////////////////////////////////////
385 // Initialization //
386 ///////////////////////////////////////////////////////////////////////////////
387 
388 //-----------------------------------------------------------------------------
389 template <typename TKSpace, typename TIterator, typename TInteger>
390 inline
391 void DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::
392 init(const ConstIterator& it)
393 {
394  ASSERT(myKSpace != nullptr);
395 
396  myBegin = it;
397  myEnd = it;
398  ++myEnd;
399 
400  SCell surfel = *it;
401  auto pair = getProjectedPointsFromSurfel(surfel);
402  auto p = myExtractor->first(pair);
403  myDSS = DSS( p );
404  auto q = myExtractor->second(pair);
405  ASSERT(myDSS.isExtendableFront( q ));
406  myDSS.extendFront( q );
407 }
408 
409 ///////////////////////////////////////////////////////////////////////////////
410 // Projection //
411 ///////////////////////////////////////////////////////////////////////////////
412 
413 //-----------------------------------------------------------------
414 template <typename TKSpace, typename TIterator, typename TInteger>
415 inline
416 std::pair<typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point,
417  typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point>
418 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::getProjectedPointsFromSurfel(SCell const& aSurfel) const
419 {
420 
421  SCell linel1;
422  //this convention has been chosen so that
423  //linels always stand at the same side
424  if (myKSpace->sSign(aSurfel) == myKSpace->POS) {
425  linel1 = myKSpace->sDirectIncident(aSurfel, myProjectionAxis);
426  } else {
427  linel1 = myKSpace->sIndirectIncident(aSurfel, myProjectionAxis);
428  }
429 
430  return getProjectedPointsFromLinel(linel1);
431 }
432 
433 //-----------------------------------------------------------------
434 template <typename TKSpace, typename TIterator, typename TInteger>
435 inline
436 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
437 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::getNextProjectedPoint(SCell const& aSurfel) const
438 {
439  return myExtractor->second(getProjectedPointsFromSurfel(aSurfel));
440 }
441 
442 //-----------------------------------------------------------------
443 template <typename TKSpace, typename TIterator, typename TInteger>
444 inline
445 typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point
446 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::getPreviousProjectedPoint(SCell const& aSurfel) const
447 {
448  return myExtractor->first(getProjectedPointsFromSurfel(aSurfel));
449 }
450 
451 ///////////////////////////////////////////////////////////////////////////////
452 // Private methods //
453 ///////////////////////////////////////////////////////////////////////////////
454 
455 
456 //-----------------------------------------------------------------
457 template <typename TKSpace, typename TIterator, typename TInteger>
458 inline
459 std::pair<typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point,
460  typename DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::Point>
461 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::getProjectedPointsFromLinel(SCell const& aLinel) const
462 {
463  auto dim = *myKSpace->sDirs(aLinel);
464 
465  auto pointel1 = myKSpace->sIndirectIncident(aLinel, dim);
466  auto p1 = my2DProjector(myKSpace->sCoords(pointel1));
467 
468  auto pointel2 = myKSpace->sDirectIncident(aLinel, dim);
469  auto p2 = my2DProjector(myKSpace->sCoords(pointel2));
470 
471  return {p1, p2};
472 }
473 
474 //-----------------------------------------------------------------
475 template <typename TKSpace, typename TIterator, typename TInteger>
476 inline
477 DGtal::Dimension
478 DGtal::ArithmeticalDSSComputerOnSurfels<TKSpace,TIterator,TInteger>::dimNotIn(Dimension const& aDim1, Dimension const& aDim2) const
479 {
480  ASSERT( KSpace::dimension == 3 );
481  ASSERT( aDim1 != aDim2 );
482 
483  bool marks[3] = {false, false, false};
484  marks[aDim1] = true;
485  marks[aDim2] = true;
486 
487  int i = 0;
488  while (marks[i] == true) {
489  i++;
490  }
491 
492  ASSERT( (marks[i] == false) && (i < 3) );
493  return i;
494 }