DGtal  1.4.beta
ArithmeticalDSL.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 ArithmeticalDSL.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 2013/06/28
23  *
24  * Implementation of inline methods defined in ArithmeticalDSL.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 // ----------------------- Standard services ------------------------------
40 
41 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
42 inline
43 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
44 ::ArithmeticalDSL(const Coordinate& aA, const Coordinate& aB,
45  const Integer& aLowerBound, const Integer& aUpperBound,
46  const Steps& aSteps, const Vector& aShift)
47  :
48  mySteps(aSteps), myShift(aShift),
49  myA(aA), myB(aB),
50  myLowerBound(aLowerBound), myUpperBound(aUpperBound)
51 {
52 }
53 
54 //-----------------------------------------------------------------------------
55 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
56 inline
57 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
58 ::ArithmeticalDSL(const Coordinate& aA, const Coordinate& aB,
59  const Integer& aMu)
60  :
61  mySteps( DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::steps(aA, aB) ),
62  myShift( DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::shift(aA, aB) ),
63  myA(aA), myB(aB),
64  myLowerBound( aMu ),
65  myUpperBound( aMu )
66 {
67  if ( (aA != 0)&&(aB !=0 ) )
68  myUpperBound = aMu + remainder( myShift ) - NumberTraits<Integer>::ONE;
69 }
70 
71 //-----------------------------------------------------------------------------
72 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
73 inline
74 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
75 ::ArithmeticalDSL(const ArithmeticalDSL<TCoordinate, TInteger, adjacency>& aOther)
76  :
77  mySteps(aOther.mySteps), myShift(aOther.myShift),
78  myA(aOther.myA), myB(aOther.myB),
79  myLowerBound(aOther.myLowerBound), myUpperBound(aOther.myUpperBound)
80 {}
81 
82 //-----------------------------------------------------------------------------
83 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
84 inline
85 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>&
86 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
87 ::operator=(const ArithmeticalDSL<TCoordinate, TInteger, adjacency>& aOther)
88 {
89  if ( this != &aOther )
90  {
91  myA = aOther.myA;
92  myB = aOther.myB;
93  myLowerBound = aOther.myLowerBound;
94  myUpperBound = aOther.myUpperBound;
95  mySteps = aOther.mySteps;
96  myShift = aOther.myShift;
97  }
98  return *this;
99 }
100 
101 //-----------------------------------------------------------------------------
102 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
103 inline
104 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
105 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
106 ::negate() const
107 {
108  return DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>(-myA, -myB, -myUpperBound, -myLowerBound,
109  std::make_pair(-mySteps.first, -mySteps.second),
110  -myShift);
111 }
112 
113 //-----------------------------------------------------------------------------
114 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
115 inline
116 bool
117 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
118 ::equalsTo(const ArithmeticalDSL<TCoordinate, TInteger, adjacency>& aOther) const
119 {
120  return ( (myA == aOther.myA) &&
121  (myB == aOther.myB) &&
122  (myLowerBound == aOther.myLowerBound) &&
123  (myUpperBound == aOther.myUpperBound) );
124  //NB: other redondant members are not tested
125 }
126 
127 //-----------------------------------------------------------------------------
128 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
129 inline
130 bool
131 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
132 ::operator==(const ArithmeticalDSL<TCoordinate, TInteger, adjacency>& aOther) const
133 {
134  return ( equalsTo(aOther) || equalsTo(aOther.negate()) );
135 }
136 
137 //-----------------------------------------------------------------------------
138 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
139 inline
140 bool
141 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
142 ::operator!=(const ArithmeticalDSL<TCoordinate, TInteger, adjacency>& aOther) const
143 {
144  return !( operator==(aOther) );
145 }
146 
147 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
148 inline
149 bool
150 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>
151 ::sameOctant( const ArithmeticalDSL & aOther, typename ArithmeticalDSL<TCoordinate, TInteger,adjacency>::Octant::first_type *theOctant ) const
152 {
153  Octant octantThis, octantOther;
154 
155  octantThis = this->octant();
156  octantOther = aOther.octant();
157 
158  if(octantThis.first==octantOther.first || octantThis.first==octantOther.second)
159  {
160  *theOctant = octantThis.first;
161  return true;
162  }
163  else
164  if(octantThis.second==octantOther.first || octantThis.second == octantOther.second)
165  {
166  *theOctant = octantThis.second;
167  return true;
168  }
169  else
170  return false;
171 }
172 
173 
174 
175 
176 // ----------------------------------------------------------------------------
177 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
178 inline
179 typename DGtal::ArithmeticalDSL<TCoordinate,TInteger,adjacency>::Octant
180 DGtal::ArithmeticalDSL<TCoordinate,TInteger, adjacency>
181 ::octant() const
182 {
183  Octant res;
184 
185  if (myB== NumberTraits<TInteger>::ZERO)
186  {
187  if (myA == NumberTraits<TInteger>::ZERO)
188  { //no octant
189  res = std::make_pair(-1,-1);
190  }
191  else if (myA > NumberTraits<TInteger>::ZERO)
192  { //octant 1,2
193  res = std::make_pair(1,2);
194  }
195  else // (myA < 0)
196  { //octant 5,6
197  res = std::make_pair(5,6);
198  }
199  }
200  else if (myB> NumberTraits<TInteger>::ZERO)
201  {
202  if (myA == NumberTraits<TInteger>::ZERO)
203  { //octant 0,7
204  res = std::make_pair(0,7);
205  }
206  else if (myA > NumberTraits<TInteger>::ZERO)
207  {
208  if (myB== myA)
209  { //octant 0,1
210  res = std::make_pair(0,1);
211  }
212  else if (myB> myA)
213  { //octant 0
214  res = std::make_pair(0,0);
215  }
216  else // (myB< myA)
217  { //octant 1
218  res = std::make_pair(1,1);
219  }
220  }
221  else //(myA < 0)
222  {
223  if (myB== -myA)
224  {
225  res = std::make_pair(6,7);
226  }
227  else if (myB> -myA)
228  { //octant 7
229  res = std::make_pair(7,7);
230  }
231  else // (myB< -myA)
232  { //octant 6
233  res = std::make_pair(6,6);
234  }
235  }
236  }
237  else // (myB< 0)
238  {
239  if (myA == NumberTraits<TInteger>::ZERO)
240  { //octant 3,4
241  res = std::make_pair(3,4);
242  }
243  else if (myA > NumberTraits<TInteger>::ZERO)
244  {
245  if (-myB == myA)
246  {
247  res = std::make_pair(2,3);
248  }
249  else if (-myB > myA)
250  { //octant 3
251  res = std::make_pair(3,3);
252  }
253  else // (-myB < myA)
254  { //octant 2
255  res = std::make_pair(2,2);
256  }
257  }
258  else // (myA < 0)
259  {
260  if (-myB== -myA)
261  {
262  res = std::make_pair(4,5);
263  }
264  else if (-myB> -myA)
265  { //octant 4
266  res = std::make_pair(4,4);
267  }
268  else // (-myB< -myA)
269  { //octant 5
270  res = std::make_pair(5,5);
271  }
272  }
273  }
274 
275 
276  return res;
277 
278 
279 }
280 
281 
282 
283 
284 
285 //-----------------------------------------------------------------------------
286 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
287 inline
288 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::~ArithmeticalDSL()
289 {
290 }
291 
292 //-----------------------------------------------------------------------------
293 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
294 inline
295 bool
296 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::isValid() const
297 {
298  bool flagIsValid; //'true' if valid, 'false' otherwise
299 
300  if ( (myA != 0) || (myB != 0) )
301  {
302  Integer gcd = IntegerComputer<Coordinate>::staticGcd(myA, myB);
303  if (gcd != NumberTraits<Coordinate>::ONE)
304  flagIsValid = false; //a,b must be relatively prime
305  else if (!checkShiftAndSteps())
306  flagIsValid = false; //redondant parameters must be consistent
307  else
308  flagIsValid = true;
309  }
310  else
311  flagIsValid = false; //a and b cannot be both null
312 
313  return flagIsValid;
314 }
315 
316 //-----------------------------------------------------------------------------
317 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
318 inline
319 bool
320 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::checkShiftAndSteps() const
321 {
322  ASSERT( (myA != 0) || (myB != 0) );
323 
324  bool flagIsValid; //'true' if valid, 'false' otherwise
325 
326  if (mySteps != DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::steps(myA, myB))
327  flagIsValid = false;
328  else if (myShift != DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::shift(myA, myB))
329  flagIsValid = false;
330  else if ( ( (mySteps.second[0] != NumberTraits<Coordinate>::ZERO)
331  ||(mySteps.second[1] != NumberTraits<Coordinate>::ZERO) )
332  &&( (mySteps.first - mySteps.second) != myShift ) )
333  flagIsValid = false;
334  else if ( remainder( myShift ) != (myUpperBound - myLowerBound + NumberTraits<Integer>::ONE) )
335  flagIsValid = false;
336  else
337  flagIsValid = true;
338 
339  return flagIsValid;
340 }
341 
342 //-----------------------------------------------------------------------------
343 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
344 inline
345 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Coordinate
346 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::a() const
347 {
348  return myA;
349 }
350 
351 //-----------------------------------------------------------------------------
352 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
353 inline
354 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Coordinate
355 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::b() const
356 {
357  return myB;
358 }
359 
360 //-----------------------------------------------------------------------------
361 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
362 inline
363 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
364 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::mu() const
365 {
366  return myLowerBound;
367 }
368 
369 //-----------------------------------------------------------------------------
370 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
371 inline
372 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
373 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::omega() const
374 {
375  return remainder(myShift);
376 }
377 
378 //-----------------------------------------------------------------------------
379 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
380 inline
381 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Position
382 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::patternLength() const
383 {
384  return ( -static_cast<Position>(myShift[1]) * static_cast<Position>(myB)
385  +static_cast<Position>(myShift[0]) * static_cast<Position>(myA) );
386 }
387 
388 //-----------------------------------------------------------------------------
389 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
390 inline
391 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Vector
392 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::shift() const
393 {
394  return myShift;
395 }
396 
397 //-----------------------------------------------------------------------------
398 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
399 inline
400 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Steps
401 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::steps() const
402 {
403  return mySteps;
404 }
405 
406 //-----------------------------------------------------------------------------
407 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
408 inline
409 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
410 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::remainder(const Coordinate& aA,
411  const Coordinate& aB,
412  const Point& aPoint)
413 {
414  return static_cast<Integer>(aA) * static_cast<Integer>(aPoint[0])
415  - static_cast<Integer>(aB) * static_cast<Integer>(aPoint[1]);
416 }
417 
418 //-----------------------------------------------------------------------------
419 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
420 inline
421 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
422 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::remainder(const Point& aPoint) const
423 {
424  return DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::remainder(myA, myB, aPoint);
425 }
426 
427 //-----------------------------------------------------------------------------
428 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
429 inline
430 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
431 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::orthogonalPosition(const Point& aPoint) const
432 {
433  return static_cast<Integer>(myB) * static_cast<Integer>(aPoint[0])
434  + static_cast<Integer>(myA) * static_cast<Integer>(aPoint[1]);
435 }
436 
437 //-----------------------------------------------------------------------------
438 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
439 inline
440 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Position
441 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::position(const Point& aPoint) const
442 {
443  return ( -static_cast<Position>(myShift[1]) * static_cast<Position>(aPoint[0])
444  +static_cast<Position>(myShift[0]) * static_cast<Position>(aPoint[1]) );
445 }
446 
447 //-----------------------------------------------------------------------------
448 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
449 inline
450 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Point
451 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::getPoint() const
452 {
453  ASSERT( omega() != NumberTraits<Integer>::ZERO );
454 
455  Integer shiftRemainder = omega();
456  Integer q = ( myLowerBound / shiftRemainder );
457  if ( (myLowerBound >= NumberTraits<Integer>::ZERO)
458  &&(myLowerBound != (q * shiftRemainder)) )
459  q++;
460  Point origin = toCoordinate(q) * myShift;
461 
462  ASSERT( position(origin) == NumberTraits<Position>::ZERO );
463  ASSERT( isInDSL(origin) );
464 
465  return origin;
466 }
467 
468 //-----------------------------------------------------------------------------
469 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
470 inline
471 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Point
472 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::getPoint(const Position& aPosition) const
473 {
474  ASSERT( omega() != NumberTraits<Integer>::ZERO );
475 
476  Integer shiftRemainder = omega();
477  Point startingPoint = static_cast<Coordinate>(aPosition) * mySteps.first;
478  Integer bound = (myLowerBound-remainder(startingPoint));
479  Integer q = ( bound / shiftRemainder );
480  if ( (bound >= NumberTraits<Integer>::ZERO)
481  &&(bound != (q * shiftRemainder)) )
482  q++;
483  Point res = startingPoint + (toCoordinate(q) * myShift);
484 
485  ASSERT( position(res) == aPosition );
486  ASSERT( isInDSL(res) );
487 
488  return res;
489 }
490 
491 //-----------------------------------------------------------------------------
492 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
493 inline
494 bool
495 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::before(const Point& aP1, const Point& aP2) const
496 {
497  return ( position( aP1 ) < position( aP2 ) );
498 }
499 
500 //-----------------------------------------------------------------------------
501 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
502 inline
503 bool
504 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::beforeOrEqual(const Point& aP1, const Point& aP2) const
505 {
506  return ( position( aP1 ) <= position( aP2 ) );
507 }
508 
509 //-----------------------------------------------------------------------------
510 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
511 inline
512 bool
513 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::isInDSL(const Point& aPoint) const
514 {
515  Integer r = remainder(aPoint);
516  return ( (r >= myLowerBound)&&(r <= myUpperBound) );
517 }
518 
519 
520 //------------------------------------------------------------------------------
521 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
522 inline
523 bool
524 DGtal::ArithmeticalDSL<TCoordinate,TInteger,adjacency>::isUpperLeaningPoint(const Point& aPoint) const
525 {
526  return (remainder(aPoint)==myLowerBound);
527 }
528 
529 //----------------------------------------------------------------------------
530 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
531 inline
532 bool
533 DGtal::ArithmeticalDSL<TCoordinate,TInteger,adjacency>::isLowerLeaningPoint(const Point& aPoint) const
534 {
535  return (remainder(aPoint)==myUpperBound);
536 }
537 
538 
539 //-----------------------------------------------------------------------------
540 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
541 inline
542 bool
543 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::operator()(const Point& aPoint) const
544 {
545  return isInDSL(aPoint);
546 }
547 
548 //-----------------------------------------------------------------------------
549 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
550 inline
551 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
552 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::begin(const Point& aPoint) const
553 {
554  ASSERT( isInDSL(aPoint) );
555  return ConstIterator(this, aPoint);
556 }
557 
558 //-----------------------------------------------------------------------------
559 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
560 inline
561 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
562 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::end(const Point& aPoint) const
563 {
564  ASSERT( isInDSL(aPoint) );
565  ConstIterator it(this, aPoint);
566  it++;
567  return it;
568 }
569 
570 //-----------------------------------------------------------------------------
571 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
572 inline
573 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstReverseIterator
574 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::rbegin(const Point& aPoint) const
575 {
576  ASSERT( isInDSL(aPoint) );
577  return ConstReverseIterator( end(aPoint) );
578 }
579 
580 //-----------------------------------------------------------------------------
581 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
582 inline
583 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstReverseIterator
584 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::rend(const Point& aPoint) const
585 {
586  ASSERT( isInDSL(aPoint) );
587  return ConstReverseIterator( begin(aPoint) );
588 }
589 
590 //-----------------------------------------------------------------------------
591 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
592 inline
593 void
594 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::selfDisplay ( std::ostream & out ) const
595 {
596  out << "[ArithmeticalDSL] ";
597  out << "(" << myA << "," << myB << "," << myLowerBound << "," << omega() << ")" << std::endl;
598  out << "by steps " << mySteps.first << " " << mySteps.second << std::endl;
599 }
600 
601 //-----------------------------------------------------------------------------
602 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
603 inline
604 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Coordinate
605 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::toCoordinate(const Integer& aI)
606 {
607  return DGtal::detail::toCoordinateImpl<Integer, Coordinate>::cast(aI);
608 }
609 
610 ///////////////////////////////////////////////////////////////////////////////
611 // Iterators services //
612 ///////////////////////////////////////////////////////////////////////////////
613 //-----------------------------------------------------------------------------
614 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
615 inline
616 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::ConstIterator()
617  : myDSLPtr(0), myCurrentPoint()
618 {
619 }
620 
621 //-----------------------------------------------------------------------------
622 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
623 inline
624 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
625 ::ConstIterator( const ArithmeticalDSL* aDSL, const Point& aPoint )
626  : myDSLPtr(aDSL), myCurrentPoint(aPoint)
627 {
628  myQuantityToAdd = myDSLPtr->remainder(myDSLPtr->mySteps.first);
629  myQuantityToRemove = myQuantityToAdd - myDSLPtr->remainder(myDSLPtr->mySteps.second);
630  myCurrentRemainder = myDSLPtr->remainder( myCurrentPoint );
631 }
632 
633 //-----------------------------------------------------------------------------
634 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
635 inline
636 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::
637 ConstIterator( const ConstIterator & aOther )
638  : myDSLPtr( aOther.myDSLPtr ), myCurrentPoint( aOther.myCurrentPoint ),
639  myQuantityToAdd( aOther.myQuantityToAdd ),
640  myQuantityToRemove( aOther.myQuantityToRemove ),
641  myCurrentRemainder( aOther.myCurrentRemainder )
642 { }
643 
644 
645 //-----------------------------------------------------------------------------
646 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
647 inline
648 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator&
649 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::
650 operator= ( const ConstIterator & aOther )
651 {
652  if (this != &aOther)
653  {
654  myDSLPtr = aOther.myDSLPtr;
655  myCurrentPoint = aOther.myCurrentPoint;
656  myQuantityToAdd = aOther.myQuantityToAdd;
657  myQuantityToRemove = aOther.myQuantityToRemove;
658  myCurrentRemainder = aOther.myCurrentRemainder;
659  }
660  return *this;
661 }
662 
663 //-----------------------------------------------------------------------------
664 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
665 inline
666 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::~ConstIterator()
667 {
668 }
669 
670 //-----------------------------------------------------------------------------
671 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
672 inline
673 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Integer
674 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::remainder() const
675 {
676  return myCurrentRemainder;
677 }
678 
679 //-----------------------------------------------------------------------------
680 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
681 inline
682 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Point const
683 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::dereference() const
684 {
685  return myCurrentPoint;
686 }
687 
688 //-----------------------------------------------------------------------------
689 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
690 inline
691 void
692 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::increment()
693 {
694  myCurrentRemainder += myQuantityToAdd;
695  if ( myCurrentRemainder <= myDSLPtr->myUpperBound )
696  {
697  myCurrentPoint += myDSLPtr->mySteps.first;
698  }
699  else
700  {
701  myCurrentRemainder -= myQuantityToRemove;
702  myCurrentPoint += myDSLPtr->mySteps.second;
703  }
704 }
705 
706 //-----------------------------------------------------------------------------
707 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
708 inline
709 void
710 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::decrement()
711 {
712  myCurrentRemainder -= myQuantityToAdd;
713  if ( myCurrentRemainder >= myDSLPtr->myLowerBound )
714  {
715  myCurrentPoint -= myDSLPtr->mySteps.first;
716  }
717  else
718  {
719  myCurrentRemainder += myQuantityToRemove;
720  myCurrentPoint -= myDSLPtr->mySteps.second;
721  }
722 }
723 
724 //-----------------------------------------------------------------------------
725 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
726 inline
727 bool
728 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator::
729 equal(const ConstIterator& aOther) const
730 {
731  ASSERT( myDSLPtr == aOther.myDSLPtr );
732  return myCurrentPoint == aOther.myCurrentPoint;
733 }
734 
735 //-----------------------------------------------------------------------------
736 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
737 inline
738 void
739 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
740 ::advance(const Position& aShift)
741 {
742  myCurrentPoint = myDSLPtr->getPoint( myDSLPtr->position(myCurrentPoint) + aShift );
743 }
744 
745 //-----------------------------------------------------------------------------
746 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
747 inline
748 typename DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::Position
749 DGtal::ArithmeticalDSL<TCoordinate, TInteger, adjacency>::ConstIterator
750 ::distance_to(const ConstIterator& aOther) const
751 {
752  return ( myDSLPtr->position(aOther.myCurrentPoint) - myDSLPtr->position(myCurrentPoint) );
753 }
754 
755 ///////////////////////////////////////////////////////////////////////////////
756 // Aliases //
757 ///////////////////////////////////////////////////////////////////////////////
758 
759 //-----------------------------------------------------------------------------
760 template <typename TCoordinate, typename TI>
761 inline
762 DGtal::StandardDSL<TCoordinate, TI>::
763 StandardDSL(const Coordinate& aA,
764  const Coordinate& aB,
765  const Integer& aMu)
766  : Super(aA, aB, aMu)
767 {}
768 
769 //-----------------------------------------------------------------------------
770 template <typename TCoordinate, typename TI>
771 inline
772 DGtal::StandardDSL<TCoordinate, TI>::
773 StandardDSL ( const StandardDSL & aOther )
774  : Super( aOther )
775 {}
776 
777 //-----------------------------------------------------------------------------
778 template <typename TCoordinate, typename TI>
779 inline
780 DGtal::StandardDSL<TCoordinate, TI>&
781 DGtal::StandardDSL<TCoordinate, TI>::
782 operator= ( const StandardDSL & aOther )
783 {
784  if (this != & aOther)
785  Super::operator=( aOther );
786  return *this;
787 }
788 
789 //-----------------------------------------------------------------------------
790 template <typename TCoordinate, typename TI>
791 inline
792 DGtal::NaiveDSL<TCoordinate, TI>::
793 NaiveDSL(const Coordinate& aA,
794  const Coordinate& aB,
795  const Integer& aMu)
796  : Super(aA, aB, aMu)
797 {}
798 
799 //-----------------------------------------------------------------------------
800 template <typename TCoordinate, typename TI>
801 inline
802 DGtal::NaiveDSL<TCoordinate, TI>::
803 NaiveDSL ( const NaiveDSL & aOther )
804  : Super( aOther )
805 {}
806 
807 //-----------------------------------------------------------------------------
808 template <typename TCoordinate, typename TI>
809 inline
810 DGtal::NaiveDSL<TCoordinate, TI>&
811 DGtal::NaiveDSL<TCoordinate, TI>::
812 operator= ( const NaiveDSL & aOther )
813 {
814  if (this != & aOther)
815  Super::operator=( aOther );
816  return *this;
817 }
818 
819 ///////////////////////////////////////////////////////////////////////////////
820 // Implementation of inline functions //
821 
822 template <typename TCoordinate, typename TInteger, unsigned short adjacency>
823 inline
824 std::ostream&
825 DGtal::operator<< ( std::ostream & out,
826  const ArithmeticalDSL<TCoordinate, TInteger, adjacency> & object )
827 {
828  object.selfDisplay( out );
829  return out;
830 }
831 
832 // //
833 ///////////////////////////////////////////////////////////////////////////////
834 
835