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.
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.
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/>.
18 * @file KhalimskySpaceND.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in KhalimskySpaceND.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
31 #include <DGtal/io/Color.h>
32 #include <DGtal/kernel/NumberTraits.h>
33 //////////////////////////////////////////////////////////////////////////////
35 ///////////////////////////////////////////////////////////////////////////////
36 // Namescape scope definition of static constants.
37 ///////////////////////////////////////////////////////////////////////////////
39 template < DGtal::Dimension dim, typename TInteger >
42 DGtal::KhalimskySpaceND<dim, TInteger>::dimension;
44 template < DGtal::Dimension dim, typename TInteger >
47 DGtal::KhalimskySpaceND<dim, TInteger>::DIM;
49 template < DGtal::Dimension dim, typename TInteger >
51 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
52 DGtal::KhalimskySpaceND<dim, TInteger>::POS;
54 template < DGtal::Dimension dim, typename TInteger >
56 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
57 DGtal::KhalimskySpaceND<dim, TInteger>::NEG;
59 ///////////////////////////////////////////////////////////////////////////////
60 // IMPLEMENTATION of inline methods.
61 ///////////////////////////////////////////////////////////////////////////////
63 ///////////////////////////////////////////////////////////////////////////////
65 ///////////////////////////////////////////////////////////////////////////////
66 //-----------------------------------------------------------------------------
67 template < DGtal::Dimension dim, typename TInteger >
69 DGtal::KhalimskyCell< dim, TInteger >::
70 KhalimskyCell( Integer )
74 //-----------------------------------------------------------------------------
75 template < DGtal::Dimension dim, typename TInteger >
77 DGtal::KhalimskyCell< dim, TInteger >::
78 KhalimskyCell( const Point & p )
82 //-----------------------------------------------------------------------------
83 template < DGtal::Dimension dim, typename TInteger >
85 DGtal::KhalimskyCell< dim, TInteger >::
86 KhalimskyCell( const PreCell & aCell )
90 //-----------------------------------------------------------------------------
91 template < DGtal::Dimension dim, typename TInteger >
93 DGtal::KhalimskyCell< dim, TInteger >::
94 operator DGtal::KhalimskyPreCell< dim, TInteger > const& () const
98 //-----------------------------------------------------------------------------
99 template < DGtal::Dimension dim, typename TInteger >
101 DGtal::KhalimskyPreCell< dim, TInteger > const &
102 DGtal::KhalimskyCell< dim, TInteger >::
107 //-----------------------------------------------------------------------------
108 template < DGtal::Dimension dim, typename TInteger >
110 DGtal::KhalimskyCell< dim, TInteger >::
111 operator DGtal::KhalimskyPreCell< dim, TInteger > & ()
115 //-----------------------------------------------------------------------------
116 template < DGtal::Dimension dim, typename TInteger >
119 DGtal::KhalimskyCell< dim, TInteger >::
120 operator==( const KhalimskyCell & other ) const
122 return myPreCell == other.myPreCell;
124 //-----------------------------------------------------------------------------
125 template < DGtal::Dimension dim, typename TInteger >
128 DGtal::KhalimskyCell< dim, TInteger >::
129 operator!=( const KhalimskyCell & other ) const
131 return myPreCell != other.myPreCell;
133 //-----------------------------------------------------------------------------
134 template < DGtal::Dimension dim, typename TInteger >
137 DGtal::KhalimskyCell< dim, TInteger >::
138 operator<( const KhalimskyCell & other ) const
140 return myPreCell < other.myPreCell;
142 //-----------------------------------------------------------------------------
143 template < DGtal::Dimension dim, typename TInteger >
146 DGtal::operator<<( std::ostream & out,
147 const KhalimskyCell< dim, TInteger > & object )
149 out << static_cast< const KhalimskyPreCell<dim, TInteger> & >(object);
153 //------------------------------------------------------------------------------
154 template < DGtal::Dimension dim, typename TInteger >
157 DGtal::KhalimskyCell<dim, TInteger>::
160 return "KhalimskyCell";
163 ///////////////////////////////////////////////////////////////////////////////
164 // SignedKhalimskyCell
165 ///////////////////////////////////////////////////////////////////////////////
166 //-----------------------------------------------------------------------------
167 template < DGtal::Dimension dim, typename TInteger >
169 DGtal::SignedKhalimskyCell< dim, TInteger >::
170 SignedKhalimskyCell( Integer )
174 //-----------------------------------------------------------------------------
175 template < DGtal::Dimension dim, typename TInteger >
177 DGtal::SignedKhalimskyCell< dim, TInteger >::
178 SignedKhalimskyCell( const Point & p, bool positive )
179 : mySPreCell( p, positive )
182 //-----------------------------------------------------------------------------
183 template < DGtal::Dimension dim, typename TInteger >
185 DGtal::SignedKhalimskyCell< dim, TInteger >::
186 SignedKhalimskyCell( const SPreCell & aCell )
187 : mySPreCell( aCell )
190 //-----------------------------------------------------------------------------
191 template < DGtal::Dimension dim, typename TInteger >
193 DGtal::SignedKhalimskyCell< dim, TInteger >::
194 operator DGtal::SignedKhalimskyPreCell< dim, TInteger > const& () const
198 //-----------------------------------------------------------------------------
199 template < DGtal::Dimension dim, typename TInteger >
201 DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
202 DGtal::SignedKhalimskyCell< dim, TInteger >::
207 //-----------------------------------------------------------------------------
208 template < DGtal::Dimension dim, typename TInteger >
210 DGtal::SignedKhalimskyCell< dim, TInteger >::
211 operator DGtal::SignedKhalimskyPreCell< dim, TInteger > & ()
215 //-----------------------------------------------------------------------------
216 template < DGtal::Dimension dim, typename TInteger >
219 DGtal::SignedKhalimskyCell< dim, TInteger >::
220 operator==( const SignedKhalimskyCell & other ) const
222 return mySPreCell == other.mySPreCell;
224 //-----------------------------------------------------------------------------
225 template < DGtal::Dimension dim, typename TInteger >
228 DGtal::SignedKhalimskyCell< dim, TInteger >::
229 operator!=( const SignedKhalimskyCell & other ) const
231 return mySPreCell != other.mySPreCell;
233 //-----------------------------------------------------------------------------
234 template < DGtal::Dimension dim, typename TInteger >
237 DGtal::SignedKhalimskyCell< dim, TInteger >::
238 operator<( const SignedKhalimskyCell & other ) const
240 return mySPreCell < other.mySPreCell;
242 //-----------------------------------------------------------------------------
243 template < DGtal::Dimension dim,
247 DGtal::operator<<( std::ostream & out,
248 const SignedKhalimskyCell< dim, TInteger > & object )
250 out << static_cast< const SignedKhalimskyPreCell<dim, TInteger> & >(object);
254 //------------------------------------------------------------------------------
255 template < DGtal::Dimension dim, typename TInteger >
258 DGtal::SignedKhalimskyCell<dim, TInteger>::
261 return "SignedKhalimskyCell";
264 ///////////////////////////////////////////////////////////////////////////////
265 // KhalimskySpaceNDHelper
266 ///////////////////////////////////////////////////////////////////////////////
271 DGtal::Dimension dim,
274 class KhalimskySpaceNDHelper< KhalimskySpaceND< dim, TInteger > >
278 using KhalimskySpace = KhalimskySpaceND< dim, TInteger >;
279 using Point = PointVector< dim, TInteger >;
280 using Cell = KhalimskyCell< dim, TInteger >;
281 using SCell = SignedKhalimskyCell< dim, TInteger >;
283 /// Returns derived mutable instance
284 KhalimskySpace& derived()
286 return *static_cast<KhalimskySpace*>(this);
289 /// Returns derived constant instance
290 KhalimskySpace const & derived() const
292 return *static_cast<KhalimskySpace const*>(this);
299 /// @return true is the specified dimension is periodic
301 bool isDimensionPeriodicHelper( DGtal::Dimension d ) const
303 return derived().myClosure[ d ] == KhalimskySpace::PERIODIC;
306 /// @return true is there is at least one periodic dimension.
308 bool isAnyDimensionPeriodicHelper() const
310 return myIsAnyDimensionPeriodic;
313 /** Modifies a khalimsky coordinate according to the dimension periodicity.
314 * @param[in,out] aKCoord the coordinate to modify.
315 * @param d the coordinate dimension.
318 void updateKCoordHelper( typename Point::Coordinate & aKCoord, DGtal::Dimension d ) const
320 if ( isDimensionPeriodicHelper( d ) )
322 aKCoord = ( aKCoord - derived().myCellLower.myPreCell.coordinates[ d ] ) % myCellExtent[ d ];
323 aKCoord += ( ( aKCoord < 0 ) ?
324 derived().myCellUpper.myPreCell.coordinates[ d ] + 1
325 : derived().myCellLower.myPreCell.coordinates[ d ]
330 /** Returns a given khalimsky coordinate modified according to the dimension periodicity.
331 * @param[in] aKCoord the coordinate to modify.
332 * @param d the coordinate dimension.
333 * @returns the modified coordinate.
336 typename Point::Coordinate returnKCoordHelper( typename Point::Coordinate aKCoord, DGtal::Dimension d ) const
338 updateKCoordHelper( aKCoord, d );
342 /** Modifies khalimsky coordinates of a point according to the dimension periodicity.
343 * @param[in,out] aKCoords the khalimksy coordinates.
346 void updateKCoordsHelper( Point & aKCoords ) const
348 if ( isAnyDimensionPeriodicHelper() )
350 for ( DGtal::Dimension i = 0; i < dim; ++i )
351 updateKCoordHelper( aKCoords[ i ], i );
355 /** Returns given khalimsky coordinates of a point modified according to the dimension periodicity.
356 * @param[in] aKCoords the khalimksy coordinates.
359 Point returnKCoordsHelper( Point aKCoords ) const
361 updateKCoordsHelper( aKCoords );
365 /** Modifies a cell's khalimsky coordinate according to the dimension periodicity.
366 * @param[in,out] aCell an unsigned cell.
367 * @param d the coordinate dimension.
370 void updateCellHelper( Cell & aCell, DGtal::Dimension d ) const
372 updateKCoordHelper( aCell.myPreCell.coordinates[ d ], d );
375 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
376 * @param[in,out] aCell an unsigned cell.
379 void updateCellHelper( Cell & aCell ) const
381 updateKCoordsHelper( aCell.myPreCell.coordinates );
384 /** Modifies a cell's khalimsky coordinate according to the dimension periodicity.
385 * @param[in,out] aCell a signed cell.
386 * @param d the coordinate dimension.
389 void updateSCellHelper( SCell & aCell, DGtal::Dimension d ) const
391 updateKCoordHelper( aCell.mySPreCell.coordinates[ d ], d );
394 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
395 * @param[in,out] aCell a signed cell.
398 void updateSCellHelper( SCell & aCell ) const
400 updateKCoordsHelper( aCell.mySPreCell.coordinates );
407 myIsAnyDimensionPeriodic = false;
408 for ( DGtal::Dimension i = 0; i < dim; ++i )
410 myIsAnyDimensionPeriodic |= isDimensionPeriodicHelper( i );
411 myCellExtent[ i ] = derived().myCellUpper.myPreCell.coordinates[ i ] - derived().myCellLower.myPreCell.coordinates[ i ] + 1;
420 Point myCellExtent; ///< Extent between the extremal cells.
421 bool myIsAnyDimensionPeriodic; ///< true if there is at least one periodic dimension.
426 ///////////////////////////////////////////////////////////////////////////////
428 ///////////////////////////////////////////////////////////////////////////////
429 ///////////////////////////////////////////////////////////////////////////////
430 // ----------------------- Standard services ------------------------------
431 //-----------------------------------------------------------------------------
432 template < DGtal::Dimension dim, typename TInteger>
434 DGtal::KhalimskySpaceND< dim, TInteger>::
438 //-----------------------------------------------------------------------------
439 template < DGtal::Dimension dim, typename TInteger>
441 DGtal::KhalimskySpaceND< dim, TInteger>::
445 for ( DGtal::Dimension i = 0; i < dimension; ++i )
447 low[ i ] = NumberTraits< Integer >::min() / 2 + 1;
448 high[ i ] = NumberTraits< Integer >::max() / 2 - 1;
450 init( low, high, true );
452 //-----------------------------------------------------------------------------
453 template < DGtal::Dimension dim, typename TInteger>
456 DGtal::KhalimskySpaceND< dim, TInteger>::
457 init( const Point & lower,
461 std::array<Closure, dimension> closure;
462 for ( DGtal::Dimension i = 0; i < dimension; ++i )
463 closure[ i ] = isClosed ? CLOSED : OPEN;
465 return init( lower, upper, closure );
467 //-----------------------------------------------------------------------------
468 template < DGtal::Dimension dim, typename TInteger>
471 DGtal::KhalimskySpaceND< dim, TInteger>::
472 init( const Point & lower,
476 std::array<Closure, dimension> dimClosure;
477 dimClosure.fill( closure );
479 return init( lower, upper, dimClosure );
482 //-----------------------------------------------------------------------------
483 template < DGtal::Dimension dim, typename TInteger>
486 DGtal::KhalimskySpaceND< dim, TInteger>::
487 init( const Point & lower,
489 const std::array<Closure, dim> & closure )
495 if ( NumberTraits< Integer >::isBounded() == BOUNDED )
497 for ( DGtal::Dimension i = 0; i < dimension; ++i )
499 if ( ( lower[ i ] <= ( NumberTraits< Integer >::min() / 2 ) )
500 || ( upper[ i ] >= ( NumberTraits< Integer >::max() / 2 ) ) )
505 for ( DGtal::Dimension i = 0; i < dimension; ++i )
507 PreCellularGridSpace::uSetKCoord( myCellLower.myPreCell, i, ( lower[ i ] * 2 ) + ( closure[ i ] != OPEN ? 0 : 1 ) );
508 PreCellularGridSpace::uSetKCoord( myCellUpper.myPreCell, i, ( upper[ i ] * 2 ) + ( closure[ i ] == CLOSED ? 2 : 1 ) );
512 return this->initHelper();
514 //-----------------------------------------------------------------------------
515 template < DGtal::Dimension dim, typename TInteger>
517 typename DGtal::KhalimskySpaceND< dim, TInteger>::Size
518 DGtal::KhalimskySpaceND< dim, TInteger>::
519 size( DGtal::Dimension k ) const
521 ASSERT( k < dimension );
522 return myUpper[ k ] + NumberTraits<Integer>::ONE - myLower[ k ];
524 //-----------------------------------------------------------------------------
525 template < DGtal::Dimension dim, typename TInteger>
528 DGtal::KhalimskySpaceND< dim, TInteger>::
529 min( DGtal::Dimension k ) const
533 //-----------------------------------------------------------------------------
534 template < DGtal::Dimension dim, typename TInteger>
537 DGtal::KhalimskySpaceND< dim, TInteger>::
538 max( DGtal::Dimension k ) const
542 //-----------------------------------------------------------------------------
543 template < DGtal::Dimension dim, typename TInteger>
545 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
546 DGtal::KhalimskySpaceND< dim, TInteger>::
551 //-----------------------------------------------------------------------------
552 template < DGtal::Dimension dim, typename TInteger>
554 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
555 DGtal::KhalimskySpaceND< dim, TInteger>::
560 //-----------------------------------------------------------------------------
561 template < DGtal::Dimension dim, typename TInteger>
563 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
564 DGtal::KhalimskySpaceND< dim, TInteger>::
569 //-----------------------------------------------------------------------------
570 template < DGtal::Dimension dim, typename TInteger>
572 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
573 DGtal::KhalimskySpaceND< dim, TInteger>::
578 //-----------------------------------------------------------------------------
579 template < DGtal::Dimension dim, typename TInteger>
582 DGtal::KhalimskySpaceND< dim, TInteger>::
583 uIsValid( const PreCell & p, Dimension k ) const
585 return cIsValid( p.coordinates, k );
587 //-----------------------------------------------------------------------------
588 template < DGtal::Dimension dim, typename TInteger>
591 DGtal::KhalimskySpaceND< dim, TInteger>::
592 uIsValid( const PreCell & p ) const
594 return cIsValid( p.coordinates );
596 //-----------------------------------------------------------------------------
597 template < DGtal::Dimension dim, typename TInteger>
600 DGtal::KhalimskySpaceND< dim, TInteger>::
601 cIsValid( const Point & p, Dimension k ) const
603 return p[ k ] <= PreCellularGridSpace::uKCoord( myCellUpper, k )
604 && p[ k ] >= PreCellularGridSpace::uKCoord( myCellLower, k );
606 //-----------------------------------------------------------------------------
607 template < DGtal::Dimension dim, typename TInteger>
610 DGtal::KhalimskySpaceND< dim, TInteger>::
611 cIsValid( const Point & p ) const
613 for ( Dimension k = 0; k < DIM; ++ k )
614 if ( ! cIsValid( p, k ) )
619 //-----------------------------------------------------------------------------
620 template < DGtal::Dimension dim, typename TInteger>
623 DGtal::KhalimskySpaceND< dim, TInteger>::
624 sIsValid( const SPreCell & p, Dimension k ) const
626 return cIsValid( p.coordinates, k );
628 //-----------------------------------------------------------------------------
629 template < DGtal::Dimension dim, typename TInteger>
632 DGtal::KhalimskySpaceND< dim, TInteger>::
633 sIsValid( const SPreCell & p ) const
635 return cIsValid( p.coordinates );
637 //-----------------------------------------------------------------------------
638 template < DGtal::Dimension dim, typename TInteger>
641 DGtal::KhalimskySpaceND< dim, TInteger>::
642 isSpaceClosed() const
644 for ( Dimension i = 0; i < dimension; ++i )
645 if ( myClosure[ i ] == OPEN )
650 //-----------------------------------------------------------------------------
651 template < DGtal::Dimension dim, typename TInteger>
654 DGtal::KhalimskySpaceND< dim, TInteger>::
655 isSpaceClosed( Dimension k ) const
657 return myClosure[ k ] != OPEN;
659 //-----------------------------------------------------------------------------
660 template < DGtal::Dimension dim, typename TInteger>
663 DGtal::KhalimskySpaceND< dim, TInteger>::
664 isSpacePeriodic() const
666 for ( Dimension i = 0; i < dimension; ++i )
667 if ( myClosure[ i ] != PERIODIC )
672 //-----------------------------------------------------------------------------
673 template < DGtal::Dimension dim, typename TInteger>
676 DGtal::KhalimskySpaceND< dim, TInteger>::
677 isSpacePeriodic( Dimension k ) const
679 return myClosure[ k ] == PERIODIC;
681 //-----------------------------------------------------------------------------
682 template < DGtal::Dimension dim, typename TInteger>
685 DGtal::KhalimskySpaceND< dim, TInteger>::
686 isAnyDimensionPeriodic() const
688 return this->isAnyDimensionPeriodicHelper();
690 //-----------------------------------------------------------------------------
691 template < DGtal::Dimension dim, typename TInteger>
693 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
694 DGtal::KhalimskySpaceND< dim, TInteger>::
695 uCell( const PreCell & c ) const
697 return uCell( c.coordinates );
699 //-----------------------------------------------------------------------------
700 template < DGtal::Dimension dim, typename TInteger>
702 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
703 DGtal::KhalimskySpaceND< dim, TInteger>::
704 uCell( const Point & kp ) const
706 ASSERT( cIsInside( kp ) );
707 return Cell( this->returnKCoordsHelper( kp ) );
709 //-----------------------------------------------------------------------------
710 template < DGtal::Dimension dim, typename TInteger>
712 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
713 DGtal::KhalimskySpaceND< dim, TInteger>::
714 uCell( Point p, const PreCell & c ) const
716 return uCell( PreCellularGridSpace::uCell( p, c ) );
718 //-----------------------------------------------------------------------------
719 template < DGtal::Dimension dim, typename TInteger>
721 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
722 DGtal::KhalimskySpaceND< dim, TInteger>::
723 sCell( const SPreCell & c ) const
725 return sCell( c.coordinates, c.positive ? POS : NEG );
727 //-----------------------------------------------------------------------------
728 template < DGtal::Dimension dim, typename TInteger>
730 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
731 DGtal::KhalimskySpaceND< dim, TInteger>::
732 sCell( const Point & kp, Sign sign ) const
734 ASSERT( cIsInside( kp ) );
735 return SCell( this->returnKCoordsHelper( kp ), sign == POS );
737 //-----------------------------------------------------------------------------
738 template < DGtal::Dimension dim, typename TInteger>
740 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
741 DGtal::KhalimskySpaceND< dim, TInteger>::
742 sCell( Point p, const SPreCell & c ) const
744 return sCell( PreCellularGridSpace::sCell( p, c ) );
746 //-----------------------------------------------------------------------------
747 template < DGtal::Dimension dim, typename TInteger>
749 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
750 DGtal::KhalimskySpaceND< dim, TInteger>::
751 uSpel( Point p ) const
753 return uCell( PreCellularGridSpace::uSpel( p ) );
755 //-----------------------------------------------------------------------------
756 template < DGtal::Dimension dim, typename TInteger>
758 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
759 DGtal::KhalimskySpaceND< dim, TInteger>::
760 sSpel( Point p, Sign sign ) const
762 return sCell( PreCellularGridSpace::sSpel( p, sign ) );
764 //-----------------------------------------------------------------------------
765 template < DGtal::Dimension dim, typename TInteger>
767 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
768 DGtal::KhalimskySpaceND< dim, TInteger>::
769 uPointel( Point p ) const
771 return uCell( PreCellularGridSpace::uPointel( p ) );
773 //-----------------------------------------------------------------------------
774 template < DGtal::Dimension dim, typename TInteger>
776 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
777 DGtal::KhalimskySpaceND< dim, TInteger>::
778 sPointel( Point p, Sign sign ) const
780 return sCell( PreCellularGridSpace::sPointel( p, sign ) );
782 //-----------------------------------------------------------------------------
783 ///////////////////////////////////////////////////////////////////////////////
784 //-----------------------------------------------------------------------------
785 template < DGtal::Dimension dim, typename TInteger>
787 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
788 DGtal::KhalimskySpaceND< dim, TInteger>::
789 uKCoord( const Cell & c, DGtal::Dimension k ) const
791 ASSERT( uIsValid(c) );
792 return PreCellularGridSpace::uKCoord( c, k );
794 //-----------------------------------------------------------------------------
795 template < DGtal::Dimension dim, typename TInteger>
797 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
798 DGtal::KhalimskySpaceND< dim, TInteger>::
799 uCoord( const Cell & c, DGtal::Dimension k ) const
801 ASSERT( uIsValid(c) );
802 return PreCellularGridSpace::uCoord( c, k );
804 //-----------------------------------------------------------------------------
805 template < DGtal::Dimension dim, typename TInteger>
807 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
808 DGtal::KhalimskySpaceND< dim, TInteger>::
809 uKCoords( const Cell & c ) const
811 ASSERT( uIsValid(c) );
812 return PreCellularGridSpace::uKCoords( c );
814 //-----------------------------------------------------------------------------
815 template < DGtal::Dimension dim, typename TInteger>
817 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
818 DGtal::KhalimskySpaceND< dim, TInteger>::
819 uCoords( const Cell & c ) const
821 ASSERT( uIsValid(c) );
822 return PreCellularGridSpace::uCoords( c );
824 //-----------------------------------------------------------------------------
825 template < DGtal::Dimension dim, typename TInteger>
827 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
828 DGtal::KhalimskySpaceND< dim, TInteger>::
829 sKCoord( const SCell & c, DGtal::Dimension k ) const
831 ASSERT( sIsValid(c) );
832 return PreCellularGridSpace::sKCoord( c, k );
834 //-----------------------------------------------------------------------------
835 template < DGtal::Dimension dim, typename TInteger>
837 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
838 DGtal::KhalimskySpaceND< dim, TInteger>::
839 sCoord( const SCell & c, DGtal::Dimension k ) const
841 ASSERT( sIsValid(c) );
842 return PreCellularGridSpace::sCoord( c, k );
844 //-----------------------------------------------------------------------------
845 template < DGtal::Dimension dim, typename TInteger>
847 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
848 DGtal::KhalimskySpaceND< dim, TInteger>::
849 sKCoords( const SCell & c ) const
851 ASSERT( sIsValid(c) );
852 return PreCellularGridSpace::sKCoords( c );
854 //-----------------------------------------------------------------------------
855 template < DGtal::Dimension dim, typename TInteger>
857 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
858 DGtal::KhalimskySpaceND< dim, TInteger>::
859 sCoords( const SCell & c ) const
861 ASSERT( sIsValid(c) );
862 return PreCellularGridSpace::sCoords( c );
864 //-----------------------------------------------------------------------------
865 template < DGtal::Dimension dim, typename TInteger>
867 typename DGtal::KhalimskySpaceND< dim, TInteger>::Sign
868 DGtal::KhalimskySpaceND< dim, TInteger>::
869 sSign( const SCell & c ) const
871 ASSERT( sIsValid(c) );
872 return PreCellularGridSpace::sSign( c );
874 //-----------------------------------------------------------------------------
875 template < DGtal::Dimension dim, typename TInteger>
877 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
878 DGtal::KhalimskySpaceND< dim, TInteger>::
879 signs( const Cell & p, Sign s ) const
881 return sCell( PreCellularGridSpace::signs( p, s ) );
883 //-----------------------------------------------------------------------------
884 template < DGtal::Dimension dim, typename TInteger>
886 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
887 DGtal::KhalimskySpaceND< dim, TInteger>::
888 unsigns( const SCell & p ) const
890 return uCell( PreCellularGridSpace::unsigns( p ) );
892 //-----------------------------------------------------------------------------
893 template < DGtal::Dimension dim, typename TInteger>
895 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
896 DGtal::KhalimskySpaceND< dim, TInteger>::
897 sOpp( const SCell & p ) const
899 return sCell( PreCellularGridSpace::sOpp( p ) );
901 //-----------------------------------------------------------------------------
902 template < DGtal::Dimension dim, typename TInteger>
905 DGtal::KhalimskySpaceND< dim, TInteger>::
906 uSetKCoord( Cell & c, DGtal::Dimension k, Integer i ) const
908 PreCellularGridSpace::uSetKCoord( c.myPreCell, k, i );
909 this->updateCellHelper( c, k );
910 ASSERT( uIsValid(c) );
912 //-----------------------------------------------------------------------------
913 template < DGtal::Dimension dim, typename TInteger>
916 DGtal::KhalimskySpaceND< dim, TInteger>::
917 sSetKCoord( SCell & c, DGtal::Dimension k, Integer i ) const
919 PreCellularGridSpace::sSetKCoord( c.mySPreCell, k, i );
920 this->updateSCellHelper( c, k );
921 ASSERT( sIsValid(c) );
923 //-----------------------------------------------------------------------------
924 template < DGtal::Dimension dim, typename TInteger>
927 DGtal::KhalimskySpaceND< dim, TInteger>::
928 uSetCoord( Cell & c, DGtal::Dimension k, Integer i ) const
930 PreCellularGridSpace::uSetCoord( c.myPreCell, k, i );
931 this->updateCellHelper( c, k );
932 ASSERT( uIsValid(c) );
934 //-----------------------------------------------------------------------------
935 template < DGtal::Dimension dim, typename TInteger>
938 DGtal::KhalimskySpaceND< dim, TInteger>::
939 sSetCoord( SCell & c, DGtal::Dimension k, Integer i ) const
941 PreCellularGridSpace::sSetCoord( c.mySPreCell, k, i );
942 this->updateSCellHelper( c, k );
943 ASSERT( sIsValid(c) );
945 //-----------------------------------------------------------------------------
946 template < DGtal::Dimension dim, typename TInteger>
949 DGtal::KhalimskySpaceND< dim, TInteger>::
950 uSetKCoords( Cell & c, const Point & kp ) const
952 PreCellularGridSpace::uSetKCoords( c.myPreCell, kp );
953 this->updateCellHelper( c );
954 ASSERT( uIsValid(c) );
956 //-----------------------------------------------------------------------------
957 template < DGtal::Dimension dim, typename TInteger>
960 DGtal::KhalimskySpaceND< dim, TInteger>::
961 sSetKCoords( SCell & c, const Point & kp ) const
963 PreCellularGridSpace::sSetKCoords( c.mySPreCell, kp );
964 this->updateSCellHelper( c );
965 ASSERT( sIsValid(c) );
967 //-----------------------------------------------------------------------------
968 template < DGtal::Dimension dim, typename TInteger>
971 DGtal::KhalimskySpaceND< dim, TInteger>::
972 uSetCoords( Cell & c, const Point & p ) const
974 PreCellularGridSpace::uSetCoords( c.myPreCell, p );
975 this->updateCellHelper( c );
976 ASSERT( uIsValid(c) );
978 //-----------------------------------------------------------------------------
979 template < DGtal::Dimension dim, typename TInteger>
982 DGtal::KhalimskySpaceND< dim, TInteger>::
983 sSetCoords( SCell & c, const Point & p ) const
985 PreCellularGridSpace::sSetCoords( c.mySPreCell, p );
986 this->updateSCellHelper( c );
987 ASSERT( sIsValid(c) );
989 //-----------------------------------------------------------------------------
990 template < DGtal::Dimension dim, typename TInteger>
993 DGtal::KhalimskySpaceND< dim, TInteger>::
994 sSetSign( SCell & c, Sign s ) const
996 PreCellularGridSpace::sSetSign( c.mySPreCell, s );
998 //-----------------------------------------------------------------------------
999 // ------------------------- Cell topology services -----------------------
1000 //-----------------------------------------------------------------------------
1001 template < DGtal::Dimension dim, typename TInteger>
1004 DGtal::KhalimskySpaceND< dim, TInteger>::
1005 uTopology( const Cell & p ) const
1007 return PreCellularGridSpace::uTopology( p );
1009 //-----------------------------------------------------------------------------
1010 template < DGtal::Dimension dim, typename TInteger>
1013 DGtal::KhalimskySpaceND< dim, TInteger>::
1014 sTopology( const SCell & p ) const
1016 return PreCellularGridSpace::sTopology( p );
1018 //-----------------------------------------------------------------------------
1019 template < DGtal::Dimension dim, typename TInteger>
1022 DGtal::KhalimskySpaceND< dim, TInteger>::
1023 uDim( const Cell & p ) const
1025 return PreCellularGridSpace::uDim( p );
1027 //-----------------------------------------------------------------------------
1028 template < DGtal::Dimension dim, typename TInteger>
1031 DGtal::KhalimskySpaceND< dim, TInteger>::
1032 sDim( const SCell & p ) const
1034 return PreCellularGridSpace::sDim( p );
1036 //-----------------------------------------------------------------------------
1037 template < DGtal::Dimension dim, typename TInteger>
1040 DGtal::KhalimskySpaceND< dim, TInteger>::
1041 uIsSurfel( const Cell & b ) const
1043 return PreCellularGridSpace::uIsSurfel( b );
1045 //-----------------------------------------------------------------------------
1046 template < DGtal::Dimension dim, typename TInteger>
1049 DGtal::KhalimskySpaceND< dim, TInteger>::
1050 sIsSurfel( const SCell & b ) const
1052 return PreCellularGridSpace::sIsSurfel( b );
1054 //-----------------------------------------------------------------------------
1055 template < DGtal::Dimension dim, typename TInteger>
1058 DGtal::KhalimskySpaceND< dim, TInteger>::
1059 uIsOpen( const Cell & p, DGtal::Dimension k ) const
1061 return PreCellularGridSpace::uIsOpen( p, k );
1063 //-----------------------------------------------------------------------------
1064 template < DGtal::Dimension dim, typename TInteger>
1067 DGtal::KhalimskySpaceND< dim, TInteger>::
1068 sIsOpen( const SCell & p, DGtal::Dimension k ) const
1070 return PreCellularGridSpace::sIsOpen( p, k );
1073 //-----------------------------------------------------------------------------
1074 ///////////////////////////////////////////////////////////////////////////////
1075 //-----------------------------------------------------------------------------
1076 template < DGtal::Dimension dim, typename TInteger>
1078 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1079 DGtal::KhalimskySpaceND< dim, TInteger>::
1080 uDirs( const Cell & p ) const
1082 return PreCellularGridSpace::uDirs( p );
1084 //-----------------------------------------------------------------------------
1085 template < DGtal::Dimension dim, typename TInteger>
1087 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1088 DGtal::KhalimskySpaceND< dim, TInteger>::
1089 sDirs( const SCell & p ) const
1091 return PreCellularGridSpace::sDirs( p );
1093 //-----------------------------------------------------------------------------
1094 template < DGtal::Dimension dim, typename TInteger>
1096 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1097 DGtal::KhalimskySpaceND< dim, TInteger>::
1098 uOrthDirs( const Cell & p ) const
1100 return PreCellularGridSpace::uOrthDirs( p );
1102 //-----------------------------------------------------------------------------
1103 template < DGtal::Dimension dim, typename TInteger>
1105 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1106 DGtal::KhalimskySpaceND< dim, TInteger>::
1107 sOrthDirs( const SCell & p ) const
1109 return PreCellularGridSpace::sOrthDirs( p );
1111 //-----------------------------------------------------------------------------
1112 template < DGtal::Dimension dim, typename TInteger>
1115 DGtal::KhalimskySpaceND< dim, TInteger>::
1116 uOrthDir( const Cell & s ) const
1118 return PreCellularGridSpace::uOrthDir( s );
1120 //-----------------------------------------------------------------------------
1121 template < DGtal::Dimension dim, typename TInteger>
1124 DGtal::KhalimskySpaceND< dim, TInteger>::
1125 sOrthDir( const SCell & s ) const
1127 return PreCellularGridSpace::sOrthDir( s );
1129 //-----------------------------------------------------------------------------
1130 ///////////////////////////////////////////////////////////////////////////////
1131 //-----------------------------------------------------------------------------
1132 //-----------------------------------------------------------------------------
1133 template < DGtal::Dimension dim, typename TInteger>
1135 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1136 DGtal::KhalimskySpaceND< dim, TInteger>::
1137 uFirst( const PreCell & p, DGtal::Dimension k ) const
1141 return myClosure[ k ] == OPEN ?
1142 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1143 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1145 //-----------------------------------------------------------------------------
1146 template < DGtal::Dimension dim, typename TInteger>
1148 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1149 DGtal::KhalimskySpaceND< dim, TInteger>::
1150 uFirst( const PreCell & p ) const
1153 for ( Dimension k = 0; k < dimension; ++k )
1154 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uFirst( p, k ) );
1158 //-----------------------------------------------------------------------------
1159 template < DGtal::Dimension dim, typename TInteger>
1161 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1162 DGtal::KhalimskySpaceND< dim, TInteger>::
1163 uLast( const PreCell & p, DGtal::Dimension k ) const
1167 return myClosure[ k ] == CLOSED ?
1168 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1169 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1171 //-----------------------------------------------------------------------------
1172 template < DGtal::Dimension dim, typename TInteger>
1174 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1175 DGtal::KhalimskySpaceND< dim, TInteger>::
1176 uLast( const PreCell & p ) const
1179 for ( Dimension k = 0; k < dimension; ++k )
1180 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uLast( p, k ) );
1184 //-----------------------------------------------------------------------------
1185 template < DGtal::Dimension dim, typename TInteger>
1187 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1188 DGtal::KhalimskySpaceND< dim, TInteger>::
1189 uGetIncr( const Cell & p, DGtal::Dimension k ) const
1191 Cell cell( PreCellularGridSpace::uGetIncr( p, k ) );
1192 this->updateCellHelper( cell, k );
1193 ASSERT( uIsValid(cell) );
1196 //-----------------------------------------------------------------------------
1197 template < DGtal::Dimension dim, typename TInteger>
1200 DGtal::KhalimskySpaceND< dim, TInteger>::
1201 uIsMax( const Cell & p, DGtal::Dimension k ) const
1204 ASSERT( uIsInside(p) );
1206 ! this->isDimensionPeriodicHelper( k )
1207 && PreCellularGridSpace::uKCoord( p, k ) >= uLast( p, k );
1209 //-----------------------------------------------------------------------------
1210 template < DGtal::Dimension dim, typename TInteger>
1213 DGtal::KhalimskySpaceND< dim, TInteger>::
1214 uIsInside( const PreCell & p, DGtal::Dimension k ) const
1216 return cIsInside( p.coordinates, k );
1218 //-----------------------------------------------------------------------------
1219 template < DGtal::Dimension dim, typename TInteger>
1222 DGtal::KhalimskySpaceND< dim, TInteger>::
1223 uIsInside( const PreCell & p ) const
1225 return cIsInside( p.coordinates );
1227 //-----------------------------------------------------------------------------
1228 template < DGtal::Dimension dim, typename TInteger>
1231 DGtal::KhalimskySpaceND< dim, TInteger>::
1232 cIsInside( const Point & p, DGtal::Dimension k ) const
1235 return this->isDimensionPeriodicHelper( k )
1236 || cIsValid( p, k );
1238 //-----------------------------------------------------------------------------
1239 template < DGtal::Dimension dim, typename TInteger>
1242 DGtal::KhalimskySpaceND< dim, TInteger>::
1243 cIsInside( const Point & p ) const
1245 for ( Dimension k = 0; k < DIM; ++k )
1246 if ( ! cIsInside( p, k ) )
1251 //-----------------------------------------------------------------------------
1252 template < DGtal::Dimension dim, typename TInteger>
1254 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1255 DGtal::KhalimskySpaceND< dim, TInteger>::
1256 uGetMax( Cell p, DGtal::Dimension k ) const
1258 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uLast( p, k ) );
1259 ASSERT( uIsValid( p ) );
1262 //-----------------------------------------------------------------------------
1263 template < DGtal::Dimension dim, typename TInteger>
1265 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1266 DGtal::KhalimskySpaceND< dim, TInteger>::
1267 uGetDecr( const Cell & p, DGtal::Dimension k ) const
1269 Cell cell( PreCellularGridSpace::uGetDecr( p, k ) );
1270 this->updateCellHelper( cell, k );
1271 ASSERT( uIsValid( cell ) );
1274 //-----------------------------------------------------------------------------
1275 template < DGtal::Dimension dim, typename TInteger>
1278 DGtal::KhalimskySpaceND< dim, TInteger>::
1279 uIsMin( const Cell & p, DGtal::Dimension k ) const
1281 ASSERT( uIsInside(p) );
1283 ! this->isDimensionPeriodicHelper( k )
1284 && PreCellularGridSpace::uKCoord( p, k ) <= uFirst( p, k );
1286 //-----------------------------------------------------------------------------
1287 template < DGtal::Dimension dim, typename TInteger>
1289 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1290 DGtal::KhalimskySpaceND< dim, TInteger>::
1291 uGetMin( Cell p, DGtal::Dimension k ) const
1293 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uFirst( p, k ) );
1294 ASSERT( uIsValid(p) );
1297 //-----------------------------------------------------------------------------
1298 template < DGtal::Dimension dim, typename TInteger>
1300 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1301 DGtal::KhalimskySpaceND< dim, TInteger>::
1302 uGetAdd( const Cell & p, DGtal::Dimension k, Integer x ) const
1304 Cell cell( PreCellularGridSpace::uGetAdd( p, k, x ) );
1305 this->updateCellHelper( cell, k );
1306 ASSERT( uIsValid( cell ) );
1309 //-----------------------------------------------------------------------------
1310 template < DGtal::Dimension dim, typename TInteger>
1312 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1313 DGtal::KhalimskySpaceND< dim, TInteger>::
1314 uGetSub( const Cell & p, DGtal::Dimension k, Integer x ) const
1316 Cell cell( PreCellularGridSpace::uGetSub( p, k, x ) );
1317 this->updateCellHelper( cell, k );
1318 ASSERT( uIsValid( cell ) );
1321 //-----------------------------------------------------------------------------
1322 template < DGtal::Dimension dim, typename TInteger>
1325 DGtal::KhalimskySpaceND< dim, TInteger>::
1326 uDistanceToMax( const Cell & p, DGtal::Dimension k ) const
1328 using KPS = PreCellularGridSpace;
1330 ASSERT( uIsValid(p) );
1331 return ( KPS::uKCoord( myCellUpper, k ) - KPS::uKCoord( p, k ) ) >> 1;
1333 //-----------------------------------------------------------------------------
1334 template < DGtal::Dimension dim, typename TInteger>
1337 DGtal::KhalimskySpaceND< dim, TInteger>::
1338 uDistanceToMin( const Cell & p, DGtal::Dimension k ) const
1340 using KPS = PreCellularGridSpace;
1342 ASSERT( uIsValid(p) );
1343 return ( KPS::uKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1345 //-----------------------------------------------------------------------------
1346 template < DGtal::Dimension dim, typename TInteger>
1348 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1349 DGtal::KhalimskySpaceND< dim, TInteger>::
1350 uTranslation( const Cell & p, const Vector & vec ) const
1352 Cell cell( PreCellularGridSpace::uTranslation( p, vec ) );
1353 this->updateCellHelper( cell );
1354 ASSERT( uIsValid( cell ) );
1357 //-----------------------------------------------------------------------------
1358 template < DGtal::Dimension dim, typename TInteger>
1360 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1361 DGtal::KhalimskySpaceND< dim, TInteger>::
1362 uProjection( const Cell & p, const Cell & bound, DGtal::Dimension k ) const
1364 Cell cell( PreCellularGridSpace::uProjection( p, bound, k ) );
1365 ASSERT( uIsValid( cell ) );
1368 //-----------------------------------------------------------------------------
1369 template < DGtal::Dimension dim, typename TInteger>
1372 DGtal::KhalimskySpaceND< dim, TInteger>::
1373 uProject( Cell & p, const Cell & bound, DGtal::Dimension k ) const
1375 PreCellularGridSpace::uProject( p.myPreCell, bound, k );
1376 ASSERT( uIsValid( p ) );
1378 //-----------------------------------------------------------------------------
1379 template < DGtal::Dimension dim, typename TInteger>
1382 DGtal::KhalimskySpaceND< dim, TInteger>::
1383 uNext( Cell & p, const Cell & lower, const Cell & upper ) const
1385 ASSERT( uIsValid(p) );
1386 ASSERT( uIsValid(lower) );
1387 ASSERT( uIsValid(upper) );
1388 ASSERT( uTopology(p) == uTopology(lower)
1389 && uTopology(p) == uTopology(upper) );
1391 using KPS = PreCellularGridSpace;
1393 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1394 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1396 if ( p == upper ) return false;
1397 KPS::uProject( p.myPreCell, lower, k );
1399 for ( k = 1; k < DIM; ++k )
1401 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1402 KPS::uProject( p.myPreCell, lower, k );
1405 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1412 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1416 //-----------------------------------------------------------------------------
1417 ///////////////////////////////////////////////////////////////////////////////
1418 //-----------------------------------------------------------------------------
1419 //-----------------------------------------------------------------------------
1420 template < DGtal::Dimension dim, typename TInteger>
1422 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1423 DGtal::KhalimskySpaceND< dim, TInteger>::
1424 sFirst( const SPreCell & p, DGtal::Dimension k ) const
1428 return myClosure[ k ] == OPEN ?
1429 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1430 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1432 //-----------------------------------------------------------------------------
1433 template < DGtal::Dimension dim, typename TInteger>
1435 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1436 DGtal::KhalimskySpaceND< dim, TInteger >::
1437 sFirst( const SPreCell & p ) const
1440 for ( Dimension k = 0; k < dimension; ++k )
1441 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sFirst( p, k ) );
1443 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1447 //-----------------------------------------------------------------------------
1448 template < DGtal::Dimension dim, typename TInteger>
1450 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1451 DGtal::KhalimskySpaceND< dim, TInteger>::
1452 sLast( const SPreCell & p, DGtal::Dimension k ) const
1455 return myClosure[ k ] == CLOSED ?
1456 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1457 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1459 //-----------------------------------------------------------------------------
1460 template < DGtal::Dimension dim, typename TInteger>
1462 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1463 DGtal::KhalimskySpaceND< dim, TInteger >::
1464 sLast( const SPreCell & p ) const
1467 for ( Dimension k = 0; k < dimension; ++k )
1468 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sLast( p, k ) );
1470 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1474 //-----------------------------------------------------------------------------
1475 template < DGtal::Dimension dim, typename TInteger>
1477 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1478 DGtal::KhalimskySpaceND< dim, TInteger >::
1479 sGetIncr( const SCell & p, DGtal::Dimension k ) const
1481 SCell cell( PreCellularGridSpace::sGetIncr( p, k ) );
1482 this->updateSCellHelper( cell, k );
1483 ASSERT( sIsValid( cell ) );
1486 //-----------------------------------------------------------------------------
1487 template < DGtal::Dimension dim, typename TInteger>
1490 DGtal::KhalimskySpaceND< dim, TInteger >::
1491 sIsMax( const SCell & p, DGtal::Dimension k ) const
1494 ASSERT( sIsInside(p) );
1496 ! this->isDimensionPeriodicHelper( k )
1497 && PreCellularGridSpace::sKCoord( p, k ) >= sLast( p, k );
1499 //-----------------------------------------------------------------------------
1500 template < DGtal::Dimension dim, typename TInteger>
1503 DGtal::KhalimskySpaceND< dim, TInteger>::
1504 sIsInside( const SPreCell & p, DGtal::Dimension k ) const
1506 return cIsInside( p.coordinates, k );
1508 //-----------------------------------------------------------------------------
1509 template < DGtal::Dimension dim, typename TInteger>
1512 DGtal::KhalimskySpaceND< dim, TInteger>::
1513 sIsInside( const SPreCell & p ) const
1515 return cIsInside( p.coordinates );
1517 //-----------------------------------------------------------------------------
1518 template < DGtal::Dimension dim, typename TInteger>
1520 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1521 DGtal::KhalimskySpaceND< dim, TInteger >::
1522 sGetMax( SCell p, DGtal::Dimension k ) const
1524 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sLast( p, k ) );
1525 ASSERT( sIsValid( p ) );
1528 //-----------------------------------------------------------------------------
1529 template < DGtal::Dimension dim, typename TInteger>
1531 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1532 DGtal::KhalimskySpaceND< dim, TInteger >::
1533 sGetDecr( const SCell & p, DGtal::Dimension k ) const
1535 SCell cell( PreCellularGridSpace::sGetDecr( p, k ) );
1536 this->updateSCellHelper( cell, k );
1537 ASSERT( sIsValid( cell ) );
1540 //-----------------------------------------------------------------------------
1541 template < DGtal::Dimension dim, typename TInteger>
1544 DGtal::KhalimskySpaceND< dim, TInteger >::
1545 sIsMin( const SCell & p, DGtal::Dimension k ) const
1548 ASSERT( sIsInside(p) );
1550 ! this->isDimensionPeriodicHelper( k )
1551 && PreCellularGridSpace::sKCoord( p, k ) <= sFirst( p, k );
1553 //-----------------------------------------------------------------------------
1554 template < DGtal::Dimension dim, typename TInteger>
1556 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1557 DGtal::KhalimskySpaceND< dim, TInteger >::
1558 sGetMin( SCell p, DGtal::Dimension k ) const
1560 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sFirst( p, k ) );
1561 ASSERT( sIsValid( p ) );
1564 //-----------------------------------------------------------------------------
1565 template < DGtal::Dimension dim, typename TInteger>
1567 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1568 DGtal::KhalimskySpaceND< dim, TInteger >::
1569 sGetAdd( const SCell & p, DGtal::Dimension k, Integer x ) const
1571 SCell cell( PreCellularGridSpace::sGetAdd( p, k, x ) );
1572 this->updateSCellHelper( cell, k );
1573 ASSERT( sIsValid( cell ) );
1576 //-----------------------------------------------------------------------------
1577 template < DGtal::Dimension dim, typename TInteger>
1579 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1580 DGtal::KhalimskySpaceND< dim, TInteger >::
1581 sGetSub( const SCell & p, DGtal::Dimension k, Integer x ) const
1583 SCell cell( PreCellularGridSpace::sGetSub( p, k, x ) );
1584 this->updateSCellHelper( cell, k );
1585 ASSERT( sIsValid( cell ) );
1588 //-----------------------------------------------------------------------------
1589 template < DGtal::Dimension dim, typename TInteger>
1592 DGtal::KhalimskySpaceND< dim, TInteger >::
1593 sDistanceToMax( const SCell & p, DGtal::Dimension k ) const
1595 using KPS = PreCellularGridSpace;
1597 ASSERT( sIsValid( p ) );
1598 return ( KPS::uKCoord( myCellUpper, k ) - KPS::sKCoord( p, k ) ) >> 1;
1600 //-----------------------------------------------------------------------------
1601 template < DGtal::Dimension dim, typename TInteger>
1604 DGtal::KhalimskySpaceND< dim, TInteger >::
1605 sDistanceToMin( const SCell & p, DGtal::Dimension k ) const
1607 using KPS = PreCellularGridSpace;
1609 ASSERT( sIsValid( p ) );
1610 return ( KPS::sKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1612 //-----------------------------------------------------------------------------
1613 template < DGtal::Dimension dim, typename TInteger>
1615 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1616 DGtal::KhalimskySpaceND< dim, TInteger >::
1617 sTranslation( const SCell & p, const Vector & vec ) const
1619 SCell cell( PreCellularGridSpace::sTranslation( p, vec ) );
1620 this->updateSCellHelper( cell );
1621 ASSERT( sIsValid( cell ) );
1624 //-----------------------------------------------------------------------------
1625 template < DGtal::Dimension dim, typename TInteger>
1627 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1628 DGtal::KhalimskySpaceND< dim, TInteger >::
1629 sProjection( const SCell & p, const SCell & bound, DGtal::Dimension k ) const
1631 SCell cell( PreCellularGridSpace::sProjection( p, bound, k ) );
1632 ASSERT( sIsValid( cell ) );
1635 //-----------------------------------------------------------------------------
1636 template < DGtal::Dimension dim, typename TInteger>
1639 DGtal::KhalimskySpaceND< dim, TInteger >::
1640 sProject( SCell & p, const SCell & bound, DGtal::Dimension k ) const
1642 PreCellularGridSpace::sProject( p.mySPreCell, bound, k );
1643 ASSERT( sIsValid( p ) );
1645 //-----------------------------------------------------------------------------
1646 template < DGtal::Dimension dim, typename TInteger>
1649 DGtal::KhalimskySpaceND< dim, TInteger >::
1650 sNext( SCell & p, const SCell & lower, const SCell & upper ) const
1652 ASSERT( sIsValid(p) );
1653 ASSERT( sIsValid(lower) );
1654 ASSERT( sIsValid(upper) );
1655 ASSERT( sTopology(p) == sTopology(lower)
1656 && sTopology(p) == sTopology(upper) );
1658 using KPS = PreCellularGridSpace;
1660 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1661 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1663 if ( p == upper ) return false;
1664 KPS::sProject( p.mySPreCell, lower, k );
1666 for ( k = 1; k < DIM; ++k )
1668 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1669 KPS::sProject( p.mySPreCell, lower, k );
1672 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1679 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1683 //-----------------------------------------------------------------------------
1684 // ----------------------- Neighborhood services --------------------------
1685 //-----------------------------------------------------------------------------
1686 template < DGtal::Dimension dim, typename TInteger>
1688 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1689 DGtal::KhalimskySpaceND< dim, TInteger >::
1690 uNeighborhood( const Cell & c ) const
1692 ASSERT( uIsValid(c) );
1696 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1698 if ( ! uIsMin( c, k ) )
1699 N.push_back( uGetDecr( c, k ) );
1700 if ( ! uIsMax( c, k ) )
1701 N.push_back( uGetIncr( c, k ) );
1705 //-----------------------------------------------------------------------------
1706 template < DGtal::Dimension dim, typename TInteger>
1708 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1709 DGtal::KhalimskySpaceND< dim, TInteger >::
1710 sNeighborhood( const SCell & c ) const
1712 ASSERT( sIsValid(c) );
1716 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1718 if ( ! sIsMin( c, k ) )
1719 N.push_back( sGetDecr( c, k ) );
1720 if ( ! sIsMax( c, k ) )
1721 N.push_back( sGetIncr( c, k ) );
1725 //-----------------------------------------------------------------------------
1726 template < DGtal::Dimension dim, typename TInteger>
1728 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1729 DGtal::KhalimskySpaceND< dim, TInteger >::
1730 uProperNeighborhood( const Cell & c ) const
1732 ASSERT( uIsValid(c) );
1735 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1737 if ( ! uIsMin( c, k ) )
1738 N.push_back( uGetDecr( c, k ) );
1739 if ( ! uIsMax( c, k ) )
1740 N.push_back( uGetIncr( c, k ) );
1744 //-----------------------------------------------------------------------------
1745 template < DGtal::Dimension dim, typename TInteger>
1747 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1748 DGtal::KhalimskySpaceND< dim, TInteger >::
1749 sProperNeighborhood( const SCell & c ) const
1751 ASSERT( sIsValid(c) );
1754 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1756 if ( ! sIsMin( c, k ) )
1757 N.push_back( sGetDecr( c, k ) );
1758 if ( ! sIsMax( c, k ) )
1759 N.push_back( sGetIncr( c, k ) );
1763 //-----------------------------------------------------------------------------
1764 template < DGtal::Dimension dim, typename TInteger>
1766 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1767 DGtal::KhalimskySpaceND< dim, TInteger >::
1768 uAdjacent( const Cell & p, DGtal::Dimension k, bool up ) const
1771 ASSERT( uIsValid(p) );
1772 ASSERT( ( up && !uIsMax(p, k) ) || ( !up && !uIsMin(p, k) ) );
1773 return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1775 //-----------------------------------------------------------------------------
1776 template < DGtal::Dimension dim, typename TInteger>
1778 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1779 DGtal::KhalimskySpaceND< dim, TInteger >::
1780 sAdjacent( const SCell & p, DGtal::Dimension k, bool up ) const
1783 ASSERT( sIsValid(p) );
1784 ASSERT( ( up && !sIsMax(p, k) ) || ( !up && !sIsMin(p, k) ) );
1785 return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1788 // ----------------------- Incidence services --------------------------
1789 //-----------------------------------------------------------------------------
1790 template < DGtal::Dimension dim, typename TInteger>
1792 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1793 DGtal::KhalimskySpaceND< dim, TInteger >::
1794 uIncident( const Cell & c, DGtal::Dimension k, bool up ) const
1797 ASSERT( uIsValid(c) );
1798 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( uKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1799 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < uKCoord( c, k ) ) );
1801 Cell cell( PreCellularGridSpace::uIncident( c, k, up ) );
1802 this->updateCellHelper( cell, k );
1806 //-----------------------------------------------------------------------------
1807 template < DGtal::Dimension dim, typename TInteger>
1809 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1810 DGtal::KhalimskySpaceND< dim, TInteger >::
1811 sIncident( const SCell & c, DGtal::Dimension k, bool up ) const
1814 ASSERT( sIsValid(c) );
1815 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( sKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1816 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < sKCoord( c, k ) ) );
1818 SCell cell( PreCellularGridSpace::sIncident( c, k, up ) );
1819 this->updateSCellHelper( cell, k );
1823 //-----------------------------------------------------------------------------
1824 template < DGtal::Dimension dim, typename TInteger>
1826 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1827 DGtal::KhalimskySpaceND< dim, TInteger >::
1828 uLowerIncident( const Cell & c ) const
1830 ASSERT( uIsValid(c) );
1833 for ( DirIterator q = uDirs( c ); q != 0; ++q )
1835 const DGtal::Dimension k = *q;
1836 if ( this->isDimensionPeriodicHelper( k ) )
1838 N.push_back( uIncident( c, k, false ) );
1839 N.push_back( uIncident( c, k, true ) );
1843 const Integer x = uKCoord( c, k );
1844 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1845 N.push_back( uIncident( c, k, false ) );
1846 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1847 N.push_back( uIncident( c, k, true ) );
1852 //-----------------------------------------------------------------------------
1853 template < DGtal::Dimension dim, typename TInteger>
1855 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1856 DGtal::KhalimskySpaceND< dim, TInteger >::
1857 uUpperIncident( const Cell & c ) const
1859 ASSERT( uIsValid(c) );
1862 for ( DirIterator q = uOrthDirs( c ); q != 0; ++q )
1864 const DGtal::Dimension k = *q;
1865 if ( this->isDimensionPeriodicHelper( k ) )
1867 N.push_back( uIncident( c, k, false ) );
1868 N.push_back( uIncident( c, k, true ) );
1872 const Integer x = uKCoord( c, k );
1873 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1874 N.push_back( uIncident( c, k, false ) );
1875 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1876 N.push_back( uIncident( c, k, true ) );
1881 //-----------------------------------------------------------------------------
1882 template < DGtal::Dimension dim, typename TInteger>
1884 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1885 DGtal::KhalimskySpaceND< dim, TInteger >::
1886 sLowerIncident( const SCell & c ) const
1888 ASSERT( sIsValid(c) );
1891 for ( DirIterator q = sDirs( c ); q != 0; ++q )
1893 const DGtal::Dimension k = *q;
1894 if ( this->isDimensionPeriodicHelper( k ) )
1896 N.push_back( sIncident( c, k, false ) );
1897 N.push_back( sIncident( c, k, true ) );
1901 const Integer x = sKCoord( c, k );
1902 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1903 N.push_back( sIncident( c, k, false ) );
1904 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1905 N.push_back( sIncident( c, k, true ) );
1910 //-----------------------------------------------------------------------------
1911 template < DGtal::Dimension dim, typename TInteger>
1913 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1914 DGtal::KhalimskySpaceND< dim, TInteger >::
1915 sUpperIncident( const SCell & c ) const
1917 ASSERT( sIsValid(c) );
1920 for ( DirIterator q = sOrthDirs( c ); q != 0; ++q )
1922 const DGtal::Dimension k = *q;
1923 if ( this->isDimensionPeriodicHelper( k ) )
1925 N.push_back( sIncident( c, k, false ) );
1926 N.push_back( sIncident( c, k, true ) );
1930 const Integer x = sKCoord( c, k );
1931 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1932 N.push_back( sIncident( c, k, false ) );
1933 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1934 N.push_back( sIncident( c, k, true ) );
1939 //-----------------------------------------------------------------------------
1940 template < DGtal::Dimension dim, typename TInteger>
1943 DGtal::KhalimskySpaceND< dim, TInteger >::
1944 uAddFaces( Cells& faces, const Cell& c, Dimension axis ) const
1946 using KPS = PreCellularGridSpace;
1948 const DGtal::Dimension dim_of_c = uDim( c );
1949 if ( axis >= dim_of_c ) return;
1951 DirIterator q = uDirs( c );
1952 for ( Dimension i = 0; i < axis; ++i ) ++q;
1954 // We test incident cells existence within the current Khalimsky space.
1955 const Integer x = KPS::uKCoord( c, *q );
1956 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
1957 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
1960 if ( has_f1 ) f1 = uIncident( c, *q, false );
1961 if ( has_f2 ) f2 = uIncident( c, *q, true );
1963 if ( has_f1 ) faces.push_back( f1 );
1964 if ( has_f2 ) faces.push_back( f2 );
1966 if ( has_f1 ) uAddFaces( faces, f1, axis );
1967 if ( has_f2 ) uAddFaces( faces, f2, axis );
1969 uAddFaces( faces, c, axis+1 );
1971 //-----------------------------------------------------------------------------
1972 template < DGtal::Dimension dim, typename TInteger>
1975 DGtal::KhalimskySpaceND< dim, TInteger >::
1976 uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis ) const
1978 using KPS = PreCellularGridSpace;
1980 const DGtal::Dimension dim_of_c = uDim( c );
1981 if ( axis >= dimension - dim_of_c ) return;
1983 DirIterator q = uOrthDirs( c );
1984 for ( Dimension i = 0; i < axis; ++i ) ++q;
1986 // We test incident cells existence within the current Khalimsky space.
1987 const Integer x = KPS::uKCoord( c, *q );
1988 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
1989 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
1992 if ( has_f1 ) f1 = uIncident( c, *q, false );
1993 if ( has_f2 ) f2 = uIncident( c, *q, true );
1995 if ( has_f1 ) cofaces.push_back( f1 );
1996 if ( has_f2 ) cofaces.push_back( f2 );
1998 if ( has_f1 ) uAddCoFaces( cofaces, f1, axis );
1999 if ( has_f2 ) uAddCoFaces( cofaces, f2, axis );
2001 uAddCoFaces( cofaces, c, axis+1 );
2003 //-----------------------------------------------------------------------------
2004 template < DGtal::Dimension dim, typename TInteger>
2006 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2007 DGtal::KhalimskySpaceND< dim, TInteger >::
2008 uFaces( const Cell & c ) const
2010 ASSERT( uIsValid(c) );
2013 uAddFaces( N, c, 0 );
2016 //-----------------------------------------------------------------------------
2017 template < DGtal::Dimension dim, typename TInteger>
2019 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2020 DGtal::KhalimskySpaceND< dim, TInteger >::
2021 uCoFaces( const Cell & c ) const
2023 ASSERT( uIsValid(c) );
2026 uAddCoFaces( N, c, 0 );
2029 //-----------------------------------------------------------------------------
2030 template < DGtal::Dimension dim, typename TInteger>
2033 DGtal::KhalimskySpaceND< dim, TInteger >::
2034 sDirect( const SCell & p, DGtal::Dimension k ) const
2036 return PreCellularGridSpace::sDirect( p, k );
2038 //-----------------------------------------------------------------------------
2039 template < DGtal::Dimension dim, typename TInteger>
2041 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2042 DGtal::KhalimskySpaceND< dim, TInteger >::
2043 sDirectIncident( const SCell & p, DGtal::Dimension k ) const
2045 using KPS = PreCellularGridSpace;
2048 ASSERT( sIsValid(p) );
2049 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2050 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2052 SCell cell( KPS::sDirectIncident( p, k ) );
2053 this->updateSCellHelper( cell, k );
2057 //-----------------------------------------------------------------------------
2058 template < DGtal::Dimension dim, typename TInteger>
2060 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2061 DGtal::KhalimskySpaceND< dim, TInteger >::
2062 sIndirectIncident( const SCell & p, DGtal::Dimension k ) const
2064 using KPS = PreCellularGridSpace;
2067 ASSERT( sIsValid(p) );
2068 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2069 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2071 SCell cell( KPS::sIndirectIncident( p, k ) );
2072 this->updateSCellHelper( cell, k );
2080 //-----------------------------------------------------------------------------
2081 template < DGtal::Dimension dim, typename TInteger>
2084 DGtal::KhalimskySpaceND< dim, TInteger>::
2085 selfDisplay ( std::ostream & out ) const
2087 out << "[KhalimskySpaceND<" << dimension << ">] { ";
2089 for ( Dimension i = 0; i < dimension; ++i )
2090 out << ( myClosure[i] == OPEN ? "OPEN " : ( myClosure[i] == CLOSED ? "CLOSED " : "PERIODIC " ) );
2092 out << "lower = " << myLower << ", ";
2093 out << "upper = " << myUpper;
2097 //-----------------------------------------------------------------------------
2098 template < DGtal::Dimension dim, typename TInteger>
2101 DGtal::KhalimskySpaceND< dim, TInteger>::
2109 ///////////////////////////////////////////////////////////////////////////////
2110 // Implementation of inline functions //
2111 template < DGtal::Dimension dim, typename TInteger>
2114 DGtal::operator<< ( std::ostream & out,
2115 const KhalimskySpaceND< dim, TInteger> & object )
2117 object.selfDisplay( out );
2122 ///////////////////////////////////////////////////////////////////////////////