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///////////////////////////////////////////////////////////////////////////////
39template < DGtal::Dimension dim, typename TInteger >
42 DGtal::KhalimskySpaceND<dim, TInteger>::dimension;
44template < DGtal::Dimension dim, typename TInteger >
47 DGtal::KhalimskySpaceND<dim, TInteger>::DIM;
49template < DGtal::Dimension dim, typename TInteger >
51 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
52 DGtal::KhalimskySpaceND<dim, TInteger>::POS;
54template < 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//-----------------------------------------------------------------------------
67template < DGtal::Dimension dim, typename TInteger >
69DGtal::KhalimskyCell< dim, TInteger >::
70KhalimskyCell( Integer )
74//-----------------------------------------------------------------------------
75template < DGtal::Dimension dim, typename TInteger >
77DGtal::KhalimskyCell< dim, TInteger >::
78KhalimskyCell( const Point & p )
82//-----------------------------------------------------------------------------
83template < DGtal::Dimension dim, typename TInteger >
85DGtal::KhalimskyCell< dim, TInteger >::
86KhalimskyCell( const PreCell & aCell )
90//-----------------------------------------------------------------------------
91template < DGtal::Dimension dim, typename TInteger >
93DGtal::KhalimskyCell< dim, TInteger >::
94operator DGtal::KhalimskyPreCell< dim, TInteger > const& () const
98//-----------------------------------------------------------------------------
99template < DGtal::Dimension dim, typename TInteger >
101DGtal::KhalimskyPreCell< dim, TInteger > const &
102DGtal::KhalimskyCell< dim, TInteger >::
107//-----------------------------------------------------------------------------
108template < DGtal::Dimension dim, typename TInteger >
110DGtal::KhalimskyCell< dim, TInteger >::
111operator DGtal::KhalimskyPreCell< dim, TInteger > & ()
115//-----------------------------------------------------------------------------
116template < DGtal::Dimension dim, typename TInteger >
119DGtal::KhalimskyCell< dim, TInteger >::
120operator==( const KhalimskyCell & other ) const
122 return myPreCell == other.myPreCell;
124//-----------------------------------------------------------------------------
125template < DGtal::Dimension dim, typename TInteger >
128DGtal::KhalimskyCell< dim, TInteger >::
129operator!=( const KhalimskyCell & other ) const
131 return myPreCell != other.myPreCell;
133//-----------------------------------------------------------------------------
134template < DGtal::Dimension dim, typename TInteger >
137DGtal::KhalimskyCell< dim, TInteger >::
138operator<( const KhalimskyCell & other ) const
140 return myPreCell < other.myPreCell;
142//-----------------------------------------------------------------------------
143template < DGtal::Dimension dim, typename TInteger >
146DGtal::operator<<( std::ostream & out,
147 const KhalimskyCell< dim, TInteger > & object )
149 out << static_cast< const KhalimskyPreCell<dim, TInteger> & >(object);
153//------------------------------------------------------------------------------
154template < DGtal::Dimension dim, typename TInteger >
157DGtal::KhalimskyCell<dim, TInteger>::
160 return "KhalimskyCell";
163///////////////////////////////////////////////////////////////////////////////
164// SignedKhalimskyCell
165///////////////////////////////////////////////////////////////////////////////
166//-----------------------------------------------------------------------------
167template < DGtal::Dimension dim, typename TInteger >
169DGtal::SignedKhalimskyCell< dim, TInteger >::
170SignedKhalimskyCell( Integer )
174//-----------------------------------------------------------------------------
175template < DGtal::Dimension dim, typename TInteger >
177DGtal::SignedKhalimskyCell< dim, TInteger >::
178SignedKhalimskyCell( const Point & p, bool positive )
179 : mySPreCell( p, positive )
182//-----------------------------------------------------------------------------
183template < DGtal::Dimension dim, typename TInteger >
185DGtal::SignedKhalimskyCell< dim, TInteger >::
186SignedKhalimskyCell( const SPreCell & aCell )
187 : mySPreCell( aCell )
190//-----------------------------------------------------------------------------
191template < DGtal::Dimension dim, typename TInteger >
193DGtal::SignedKhalimskyCell< dim, TInteger >::
194operator DGtal::SignedKhalimskyPreCell< dim, TInteger > const& () const
198//-----------------------------------------------------------------------------
199template < DGtal::Dimension dim, typename TInteger >
201DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
202DGtal::SignedKhalimskyCell< dim, TInteger >::
207//-----------------------------------------------------------------------------
208template < DGtal::Dimension dim, typename TInteger >
210DGtal::SignedKhalimskyCell< dim, TInteger >::
211operator DGtal::SignedKhalimskyPreCell< dim, TInteger > & ()
215//-----------------------------------------------------------------------------
216template < DGtal::Dimension dim, typename TInteger >
219DGtal::SignedKhalimskyCell< dim, TInteger >::
220operator==( const SignedKhalimskyCell & other ) const
222 return mySPreCell == other.mySPreCell;
224//-----------------------------------------------------------------------------
225template < DGtal::Dimension dim, typename TInteger >
228DGtal::SignedKhalimskyCell< dim, TInteger >::
229operator!=( const SignedKhalimskyCell & other ) const
231 return mySPreCell != other.mySPreCell;
233//-----------------------------------------------------------------------------
234template < DGtal::Dimension dim, typename TInteger >
237DGtal::SignedKhalimskyCell< dim, TInteger >::
238operator<( const SignedKhalimskyCell & other ) const
240 return mySPreCell < other.mySPreCell;
242//-----------------------------------------------------------------------------
243template < DGtal::Dimension dim,
247DGtal::operator<<( std::ostream & out,
248 const SignedKhalimskyCell< dim, TInteger > & object )
250 out << static_cast< const SignedKhalimskyPreCell<dim, TInteger> & >(object);
254//------------------------------------------------------------------------------
255template < DGtal::Dimension dim, typename TInteger >
258DGtal::SignedKhalimskyCell<dim, TInteger>::
261 return "SignedKhalimskyCell";
264///////////////////////////////////////////////////////////////////////////////
265// KhalimskySpaceNDHelper
266///////////////////////////////////////////////////////////////////////////////
271 DGtal::Dimension dim,
274class 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//-----------------------------------------------------------------------------
432template < DGtal::Dimension dim, typename TInteger>
434DGtal::KhalimskySpaceND< dim, TInteger>::
438//-----------------------------------------------------------------------------
439template < DGtal::Dimension dim, typename TInteger>
441DGtal::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//-----------------------------------------------------------------------------
453template < DGtal::Dimension dim, typename TInteger>
456DGtal::KhalimskySpaceND< dim, TInteger>::
457init( 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//-----------------------------------------------------------------------------
468template < DGtal::Dimension dim, typename TInteger>
471DGtal::KhalimskySpaceND< dim, TInteger>::
472init( const Point & lower,
476 std::array<Closure, dimension> dimClosure;
477 dimClosure.fill( closure );
479 return init( lower, upper, dimClosure );
482//-----------------------------------------------------------------------------
483template < DGtal::Dimension dim, typename TInteger>
486DGtal::KhalimskySpaceND< dim, TInteger>::
487init( 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//-----------------------------------------------------------------------------
515template < DGtal::Dimension dim, typename TInteger>
517typename DGtal::KhalimskySpaceND< dim, TInteger>::Size
518DGtal::KhalimskySpaceND< dim, TInteger>::
519size( DGtal::Dimension k ) const
521 ASSERT( k < dimension );
522 return myUpper[ k ] + NumberTraits<Integer>::ONE - myLower[ k ];
524//-----------------------------------------------------------------------------
525template < DGtal::Dimension dim, typename TInteger>
528DGtal::KhalimskySpaceND< dim, TInteger>::
529min( DGtal::Dimension k ) const
533//-----------------------------------------------------------------------------
534template < DGtal::Dimension dim, typename TInteger>
537DGtal::KhalimskySpaceND< dim, TInteger>::
538max( DGtal::Dimension k ) const
542//-----------------------------------------------------------------------------
543template < DGtal::Dimension dim, typename TInteger>
545const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
546DGtal::KhalimskySpaceND< dim, TInteger>::
551//-----------------------------------------------------------------------------
552template < DGtal::Dimension dim, typename TInteger>
554const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
555DGtal::KhalimskySpaceND< dim, TInteger>::
560//-----------------------------------------------------------------------------
561template < DGtal::Dimension dim, typename TInteger>
563const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
564DGtal::KhalimskySpaceND< dim, TInteger>::
569//-----------------------------------------------------------------------------
570template < DGtal::Dimension dim, typename TInteger>
572const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
573DGtal::KhalimskySpaceND< dim, TInteger>::
578//-----------------------------------------------------------------------------
579template < DGtal::Dimension dim, typename TInteger>
582DGtal::KhalimskySpaceND< dim, TInteger>::
583uIsValid( const PreCell & p, Dimension k ) const
585 return cIsValid( p.coordinates, k );
587//-----------------------------------------------------------------------------
588template < DGtal::Dimension dim, typename TInteger>
591DGtal::KhalimskySpaceND< dim, TInteger>::
592uIsValid( const PreCell & p ) const
594 return cIsValid( p.coordinates );
596//-----------------------------------------------------------------------------
597template < DGtal::Dimension dim, typename TInteger>
600DGtal::KhalimskySpaceND< dim, TInteger>::
601cIsValid( const Point & p, Dimension k ) const
603 return p[ k ] <= PreCellularGridSpace::uKCoord( myCellUpper, k )
604 && p[ k ] >= PreCellularGridSpace::uKCoord( myCellLower, k );
606//-----------------------------------------------------------------------------
607template < DGtal::Dimension dim, typename TInteger>
610DGtal::KhalimskySpaceND< dim, TInteger>::
611cIsValid( const Point & p ) const
613 for ( Dimension k = 0; k < DIM; ++ k )
614 if ( ! cIsValid( p, k ) )
619//-----------------------------------------------------------------------------
620template < DGtal::Dimension dim, typename TInteger>
623DGtal::KhalimskySpaceND< dim, TInteger>::
624sIsValid( const SPreCell & p, Dimension k ) const
626 return cIsValid( p.coordinates, k );
628//-----------------------------------------------------------------------------
629template < DGtal::Dimension dim, typename TInteger>
632DGtal::KhalimskySpaceND< dim, TInteger>::
633sIsValid( const SPreCell & p ) const
635 return cIsValid( p.coordinates );
637//-----------------------------------------------------------------------------
638template < DGtal::Dimension dim, typename TInteger>
641DGtal::KhalimskySpaceND< dim, TInteger>::
644 for ( Dimension i = 0; i < dimension; ++i )
645 if ( myClosure[ i ] == OPEN )
650//-----------------------------------------------------------------------------
651template < DGtal::Dimension dim, typename TInteger>
654DGtal::KhalimskySpaceND< dim, TInteger>::
655isSpaceClosed( Dimension k ) const
657 return myClosure[ k ] != OPEN;
659//-----------------------------------------------------------------------------
660template < DGtal::Dimension dim, typename TInteger>
663DGtal::KhalimskySpaceND< dim, TInteger>::
664isSpacePeriodic() const
666 for ( Dimension i = 0; i < dimension; ++i )
667 if ( myClosure[ i ] != PERIODIC )
672//-----------------------------------------------------------------------------
673template < DGtal::Dimension dim, typename TInteger>
676DGtal::KhalimskySpaceND< dim, TInteger>::
677isSpacePeriodic( Dimension k ) const
679 return myClosure[ k ] == PERIODIC;
681//-----------------------------------------------------------------------------
682template < DGtal::Dimension dim, typename TInteger>
685DGtal::KhalimskySpaceND< dim, TInteger>::
686isAnyDimensionPeriodic() const
688 return this->isAnyDimensionPeriodicHelper();
690//-----------------------------------------------------------------------------
691template < DGtal::Dimension dim, typename TInteger>
693typename DGtal::KhalimskySpaceND< dim, TInteger>::Closure
694DGtal::KhalimskySpaceND< dim, TInteger>::
695getClosure(Dimension k) const
699//-----------------------------------------------------------------------------
700template < DGtal::Dimension dim, typename TInteger>
702typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
703DGtal::KhalimskySpaceND< dim, TInteger>::
704uCell( const PreCell & c ) const
706 return uCell( c.coordinates );
708//-----------------------------------------------------------------------------
709template < DGtal::Dimension dim, typename TInteger>
711typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
712DGtal::KhalimskySpaceND< dim, TInteger>::
713uCell( const Point & kp ) const
715 ASSERT( cIsInside( kp ) );
716 return Cell( this->returnKCoordsHelper( kp ) );
718//-----------------------------------------------------------------------------
719template < DGtal::Dimension dim, typename TInteger>
721typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
722DGtal::KhalimskySpaceND< dim, TInteger>::
723uCell( Point p, const PreCell & c ) const
725 return uCell( PreCellularGridSpace::uCell( p, c ) );
727//-----------------------------------------------------------------------------
728template < DGtal::Dimension dim, typename TInteger>
730typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
731DGtal::KhalimskySpaceND< dim, TInteger>::
732sCell( const SPreCell & c ) const
734 return sCell( c.coordinates, c.positive ? POS : NEG );
736//-----------------------------------------------------------------------------
737template < DGtal::Dimension dim, typename TInteger>
739typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
740DGtal::KhalimskySpaceND< dim, TInteger>::
741sCell( const Point & kp, Sign sign ) const
743 ASSERT( cIsInside( kp ) );
744 return SCell( this->returnKCoordsHelper( kp ), sign == POS );
746//-----------------------------------------------------------------------------
747template < DGtal::Dimension dim, typename TInteger>
749typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
750DGtal::KhalimskySpaceND< dim, TInteger>::
751sCell( Point p, const SPreCell & c ) const
753 return sCell( PreCellularGridSpace::sCell( p, c ) );
755//-----------------------------------------------------------------------------
756template < DGtal::Dimension dim, typename TInteger>
758typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
759DGtal::KhalimskySpaceND< dim, TInteger>::
760uSpel( Point p ) const
762 return uCell( PreCellularGridSpace::uSpel( p ) );
764//-----------------------------------------------------------------------------
765template < DGtal::Dimension dim, typename TInteger>
767typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
768DGtal::KhalimskySpaceND< dim, TInteger>::
769sSpel( Point p, Sign sign ) const
771 return sCell( PreCellularGridSpace::sSpel( p, sign ) );
773//-----------------------------------------------------------------------------
774template < DGtal::Dimension dim, typename TInteger>
776typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
777DGtal::KhalimskySpaceND< dim, TInteger>::
778uPointel( Point p ) const
780 return uCell( PreCellularGridSpace::uPointel( p ) );
782//-----------------------------------------------------------------------------
783template < DGtal::Dimension dim, typename TInteger>
785typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
786DGtal::KhalimskySpaceND< dim, TInteger>::
787sPointel( Point p, Sign sign ) const
789 return sCell( PreCellularGridSpace::sPointel( p, sign ) );
791//-----------------------------------------------------------------------------
792///////////////////////////////////////////////////////////////////////////////
793//-----------------------------------------------------------------------------
794template < DGtal::Dimension dim, typename TInteger>
796typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
797DGtal::KhalimskySpaceND< dim, TInteger>::
798uKCoord( const Cell & c, DGtal::Dimension k ) const
800 ASSERT( uIsValid(c) );
801 return PreCellularGridSpace::uKCoord( c, k );
803//-----------------------------------------------------------------------------
804template < DGtal::Dimension dim, typename TInteger>
806typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
807DGtal::KhalimskySpaceND< dim, TInteger>::
808uCoord( const Cell & c, DGtal::Dimension k ) const
810 ASSERT( uIsValid(c) );
811 return PreCellularGridSpace::uCoord( c, k );
813//-----------------------------------------------------------------------------
814template < DGtal::Dimension dim, typename TInteger>
816typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
817DGtal::KhalimskySpaceND< dim, TInteger>::
818uKCoords( const Cell & c ) const
820 ASSERT( uIsValid(c) );
821 return PreCellularGridSpace::uKCoords( c );
823//-----------------------------------------------------------------------------
824template < DGtal::Dimension dim, typename TInteger>
826typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
827DGtal::KhalimskySpaceND< dim, TInteger>::
828uCoords( const Cell & c ) const
830 ASSERT( uIsValid(c) );
831 return PreCellularGridSpace::uCoords( c );
833//-----------------------------------------------------------------------------
834template < DGtal::Dimension dim, typename TInteger>
836typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
837DGtal::KhalimskySpaceND< dim, TInteger>::
838interiorVoxel( const SCell & sc ) const
840 ASSERT( sIsValid(sc) );
841 return PreCellularGridSpace::interiorVoxel( sc );
843//-----------------------------------------------------------------------------
844template < DGtal::Dimension dim, typename TInteger>
846typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
847DGtal::KhalimskySpaceND< dim, TInteger>::
848exteriorVoxel( const SCell & sc ) const
850 ASSERT( sIsValid(sc) );
851 return PreCellularGridSpace::exteriorVoxel( sc );
853//-----------------------------------------------------------------------------
854template < DGtal::Dimension dim, typename TInteger>
856typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
857DGtal::KhalimskySpaceND< dim, TInteger>::
858sKCoord( const SCell & c, DGtal::Dimension k ) const
860 ASSERT( sIsValid(c) );
861 return PreCellularGridSpace::sKCoord( c, k );
863//-----------------------------------------------------------------------------
864template < DGtal::Dimension dim, typename TInteger>
866typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
867DGtal::KhalimskySpaceND< dim, TInteger>::
868sCoord( const SCell & c, DGtal::Dimension k ) const
870 ASSERT( sIsValid(c) );
871 return PreCellularGridSpace::sCoord( c, k );
873//-----------------------------------------------------------------------------
874template < DGtal::Dimension dim, typename TInteger>
876typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
877DGtal::KhalimskySpaceND< dim, TInteger>::
878sKCoords( const SCell & c ) const
880 ASSERT( sIsValid(c) );
881 return PreCellularGridSpace::sKCoords( c );
883//-----------------------------------------------------------------------------
884template < DGtal::Dimension dim, typename TInteger>
886typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
887DGtal::KhalimskySpaceND< dim, TInteger>::
888sCoords( const SCell & c ) const
890 ASSERT( sIsValid(c) );
891 return PreCellularGridSpace::sCoords( c );
893//-----------------------------------------------------------------------------
894template < DGtal::Dimension dim, typename TInteger>
896typename DGtal::KhalimskySpaceND< dim, TInteger>::Sign
897DGtal::KhalimskySpaceND< dim, TInteger>::
898sSign( const SCell & c ) const
900 ASSERT( sIsValid(c) );
901 return PreCellularGridSpace::sSign( c );
903//-----------------------------------------------------------------------------
904template < DGtal::Dimension dim, typename TInteger>
906typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
907DGtal::KhalimskySpaceND< dim, TInteger>::
908signs( const Cell & p, Sign s ) const
910 return sCell( PreCellularGridSpace::signs( p, s ) );
912//-----------------------------------------------------------------------------
913template < DGtal::Dimension dim, typename TInteger>
915typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
916DGtal::KhalimskySpaceND< dim, TInteger>::
917unsigns( const SCell & p ) const
919 return uCell( PreCellularGridSpace::unsigns( p ) );
921//-----------------------------------------------------------------------------
922template < DGtal::Dimension dim, typename TInteger>
924typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
925DGtal::KhalimskySpaceND< dim, TInteger>::
926sOpp( const SCell & p ) const
928 return sCell( PreCellularGridSpace::sOpp( p ) );
930//-----------------------------------------------------------------------------
931template < DGtal::Dimension dim, typename TInteger>
934DGtal::KhalimskySpaceND< dim, TInteger>::
935uSetKCoord( Cell & c, DGtal::Dimension k, Integer i ) const
937 PreCellularGridSpace::uSetKCoord( c.myPreCell, k, i );
938 this->updateCellHelper( c, k );
939 ASSERT( uIsValid(c) );
941//-----------------------------------------------------------------------------
942template < DGtal::Dimension dim, typename TInteger>
945DGtal::KhalimskySpaceND< dim, TInteger>::
946sSetKCoord( SCell & c, DGtal::Dimension k, Integer i ) const
948 PreCellularGridSpace::sSetKCoord( c.mySPreCell, k, i );
949 this->updateSCellHelper( c, k );
950 ASSERT( sIsValid(c) );
952//-----------------------------------------------------------------------------
953template < DGtal::Dimension dim, typename TInteger>
956DGtal::KhalimskySpaceND< dim, TInteger>::
957uSetCoord( Cell & c, DGtal::Dimension k, Integer i ) const
959 PreCellularGridSpace::uSetCoord( c.myPreCell, k, i );
960 this->updateCellHelper( c, k );
961 ASSERT( uIsValid(c) );
963//-----------------------------------------------------------------------------
964template < DGtal::Dimension dim, typename TInteger>
967DGtal::KhalimskySpaceND< dim, TInteger>::
968sSetCoord( SCell & c, DGtal::Dimension k, Integer i ) const
970 PreCellularGridSpace::sSetCoord( c.mySPreCell, k, i );
971 this->updateSCellHelper( c, k );
972 ASSERT( sIsValid(c) );
974//-----------------------------------------------------------------------------
975template < DGtal::Dimension dim, typename TInteger>
978DGtal::KhalimskySpaceND< dim, TInteger>::
979uSetKCoords( Cell & c, const Point & kp ) const
981 PreCellularGridSpace::uSetKCoords( c.myPreCell, kp );
982 this->updateCellHelper( c );
983 ASSERT( uIsValid(c) );
985//-----------------------------------------------------------------------------
986template < DGtal::Dimension dim, typename TInteger>
989DGtal::KhalimskySpaceND< dim, TInteger>::
990sSetKCoords( SCell & c, const Point & kp ) const
992 PreCellularGridSpace::sSetKCoords( c.mySPreCell, kp );
993 this->updateSCellHelper( c );
994 ASSERT( sIsValid(c) );
996//-----------------------------------------------------------------------------
997template < DGtal::Dimension dim, typename TInteger>
1000DGtal::KhalimskySpaceND< dim, TInteger>::
1001uSetCoords( Cell & c, const Point & p ) const
1003 PreCellularGridSpace::uSetCoords( c.myPreCell, p );
1004 this->updateCellHelper( c );
1005 ASSERT( uIsValid(c) );
1007//-----------------------------------------------------------------------------
1008template < DGtal::Dimension dim, typename TInteger>
1011DGtal::KhalimskySpaceND< dim, TInteger>::
1012sSetCoords( SCell & c, const Point & p ) const
1014 PreCellularGridSpace::sSetCoords( c.mySPreCell, p );
1015 this->updateSCellHelper( c );
1016 ASSERT( sIsValid(c) );
1018//-----------------------------------------------------------------------------
1019template < DGtal::Dimension dim, typename TInteger>
1022DGtal::KhalimskySpaceND< dim, TInteger>::
1023sSetSign( SCell & c, Sign s ) const
1025 PreCellularGridSpace::sSetSign( c.mySPreCell, s );
1027//-----------------------------------------------------------------------------
1028// ------------------------- Cell topology services -----------------------
1029//-----------------------------------------------------------------------------
1030template < DGtal::Dimension dim, typename TInteger>
1033DGtal::KhalimskySpaceND< dim, TInteger>::
1034uTopology( const Cell & p ) const
1036 return PreCellularGridSpace::uTopology( p );
1038//-----------------------------------------------------------------------------
1039template < DGtal::Dimension dim, typename TInteger>
1042DGtal::KhalimskySpaceND< dim, TInteger>::
1043sTopology( const SCell & p ) const
1045 return PreCellularGridSpace::sTopology( p );
1047//-----------------------------------------------------------------------------
1048template < DGtal::Dimension dim, typename TInteger>
1051DGtal::KhalimskySpaceND< dim, TInteger>::
1052uDim( const Cell & p ) const
1054 return PreCellularGridSpace::uDim( p );
1056//-----------------------------------------------------------------------------
1057template < DGtal::Dimension dim, typename TInteger>
1060DGtal::KhalimskySpaceND< dim, TInteger>::
1061sDim( const SCell & p ) const
1063 return PreCellularGridSpace::sDim( p );
1065//-----------------------------------------------------------------------------
1066template < DGtal::Dimension dim, typename TInteger>
1069DGtal::KhalimskySpaceND< dim, TInteger>::
1070uIsSurfel( const Cell & b ) const
1072 return PreCellularGridSpace::uIsSurfel( b );
1074//-----------------------------------------------------------------------------
1075template < DGtal::Dimension dim, typename TInteger>
1078DGtal::KhalimskySpaceND< dim, TInteger>::
1079sIsSurfel( const SCell & b ) const
1081 return PreCellularGridSpace::sIsSurfel( b );
1083//-----------------------------------------------------------------------------
1084template < DGtal::Dimension dim, typename TInteger>
1087DGtal::KhalimskySpaceND< dim, TInteger>::
1088uIsOpen( const Cell & p, DGtal::Dimension k ) const
1090 return PreCellularGridSpace::uIsOpen( p, k );
1092//-----------------------------------------------------------------------------
1093template < DGtal::Dimension dim, typename TInteger>
1096DGtal::KhalimskySpaceND< dim, TInteger>::
1097sIsOpen( const SCell & p, DGtal::Dimension k ) const
1099 return PreCellularGridSpace::sIsOpen( p, k );
1102//-----------------------------------------------------------------------------
1103///////////////////////////////////////////////////////////////////////////////
1104//-----------------------------------------------------------------------------
1105template < DGtal::Dimension dim, typename TInteger>
1107typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1108DGtal::KhalimskySpaceND< dim, TInteger>::
1109uDirs( const Cell & p ) const
1111 return PreCellularGridSpace::uDirs( p );
1113//-----------------------------------------------------------------------------
1114template < DGtal::Dimension dim, typename TInteger>
1116typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1117DGtal::KhalimskySpaceND< dim, TInteger>::
1118sDirs( const SCell & p ) const
1120 return PreCellularGridSpace::sDirs( p );
1122//-----------------------------------------------------------------------------
1123template < DGtal::Dimension dim, typename TInteger>
1125typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1126DGtal::KhalimskySpaceND< dim, TInteger>::
1127uOrthDirs( const Cell & p ) const
1129 return PreCellularGridSpace::uOrthDirs( p );
1131//-----------------------------------------------------------------------------
1132template < DGtal::Dimension dim, typename TInteger>
1134typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1135DGtal::KhalimskySpaceND< dim, TInteger>::
1136sOrthDirs( const SCell & p ) const
1138 return PreCellularGridSpace::sOrthDirs( p );
1140//-----------------------------------------------------------------------------
1141template < DGtal::Dimension dim, typename TInteger>
1144DGtal::KhalimskySpaceND< dim, TInteger>::
1145uOrthDir( const Cell & s ) const
1147 return PreCellularGridSpace::uOrthDir( s );
1149//-----------------------------------------------------------------------------
1150template < DGtal::Dimension dim, typename TInteger>
1153DGtal::KhalimskySpaceND< dim, TInteger>::
1154sOrthDir( const SCell & s ) const
1156 return PreCellularGridSpace::sOrthDir( s );
1158//-----------------------------------------------------------------------------
1159///////////////////////////////////////////////////////////////////////////////
1160//-----------------------------------------------------------------------------
1161//-----------------------------------------------------------------------------
1162template < DGtal::Dimension dim, typename TInteger>
1164typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1165DGtal::KhalimskySpaceND< dim, TInteger>::
1166uFirst( const PreCell & p, DGtal::Dimension k ) const
1170 return myClosure[ k ] == OPEN ?
1171 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1172 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1174//-----------------------------------------------------------------------------
1175template < DGtal::Dimension dim, typename TInteger>
1177typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1178DGtal::KhalimskySpaceND< dim, TInteger>::
1179uFirst( const PreCell & p ) const
1182 for ( Dimension k = 0; k < dimension; ++k )
1183 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uFirst( p, k ) );
1187//-----------------------------------------------------------------------------
1188template < DGtal::Dimension dim, typename TInteger>
1190typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1191DGtal::KhalimskySpaceND< dim, TInteger>::
1192uLast( const PreCell & p, DGtal::Dimension k ) const
1196 return myClosure[ k ] == CLOSED ?
1197 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1198 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1200//-----------------------------------------------------------------------------
1201template < DGtal::Dimension dim, typename TInteger>
1203typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1204DGtal::KhalimskySpaceND< dim, TInteger>::
1205uLast( const PreCell & p ) const
1208 for ( Dimension k = 0; k < dimension; ++k )
1209 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uLast( p, k ) );
1213//-----------------------------------------------------------------------------
1214template < DGtal::Dimension dim, typename TInteger>
1216typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1217DGtal::KhalimskySpaceND< dim, TInteger>::
1218uGetIncr( const Cell & p, DGtal::Dimension k ) const
1220 Cell cell( PreCellularGridSpace::uGetIncr( p, k ) );
1221 this->updateCellHelper( cell, k );
1222 ASSERT( uIsValid(cell) );
1225//-----------------------------------------------------------------------------
1226template < DGtal::Dimension dim, typename TInteger>
1229DGtal::KhalimskySpaceND< dim, TInteger>::
1230uIsMax( const Cell & p, DGtal::Dimension k ) const
1233 ASSERT( uIsInside(p) );
1235 ! this->isDimensionPeriodicHelper( k )
1236 && PreCellularGridSpace::uKCoord( p, k ) >= uLast( p, k );
1238//-----------------------------------------------------------------------------
1239template < DGtal::Dimension dim, typename TInteger>
1242DGtal::KhalimskySpaceND< dim, TInteger>::
1243uIsInside( const PreCell & p, DGtal::Dimension k ) const
1245 return cIsInside( p.coordinates, k );
1247//-----------------------------------------------------------------------------
1248template < DGtal::Dimension dim, typename TInteger>
1251DGtal::KhalimskySpaceND< dim, TInteger>::
1252uIsInside( const PreCell & p ) const
1254 return cIsInside( p.coordinates );
1256//-----------------------------------------------------------------------------
1257template < DGtal::Dimension dim, typename TInteger>
1260DGtal::KhalimskySpaceND< dim, TInteger>::
1261cIsInside( const Point & p, DGtal::Dimension k ) const
1264 return this->isDimensionPeriodicHelper( k )
1265 || cIsValid( p, k );
1267//-----------------------------------------------------------------------------
1268template < DGtal::Dimension dim, typename TInteger>
1271DGtal::KhalimskySpaceND< dim, TInteger>::
1272cIsInside( const Point & p ) const
1274 for ( Dimension k = 0; k < DIM; ++k )
1275 if ( ! cIsInside( p, k ) )
1280//-----------------------------------------------------------------------------
1281template < DGtal::Dimension dim, typename TInteger>
1283typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1284DGtal::KhalimskySpaceND< dim, TInteger>::
1285uGetMax( Cell p, DGtal::Dimension k ) const
1287 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uLast( p, k ) );
1288 ASSERT( uIsValid( p ) );
1291//-----------------------------------------------------------------------------
1292template < DGtal::Dimension dim, typename TInteger>
1294typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1295DGtal::KhalimskySpaceND< dim, TInteger>::
1296uGetDecr( const Cell & p, DGtal::Dimension k ) const
1298 Cell cell( PreCellularGridSpace::uGetDecr( p, k ) );
1299 this->updateCellHelper( cell, k );
1300 ASSERT( uIsValid( cell ) );
1303//-----------------------------------------------------------------------------
1304template < DGtal::Dimension dim, typename TInteger>
1307DGtal::KhalimskySpaceND< dim, TInteger>::
1308uIsMin( const Cell & p, DGtal::Dimension k ) const
1310 ASSERT( uIsInside(p) );
1312 ! this->isDimensionPeriodicHelper( k )
1313 && PreCellularGridSpace::uKCoord( p, k ) <= uFirst( p, k );
1315//-----------------------------------------------------------------------------
1316template < DGtal::Dimension dim, typename TInteger>
1318typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1319DGtal::KhalimskySpaceND< dim, TInteger>::
1320uGetMin( Cell p, DGtal::Dimension k ) const
1322 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uFirst( p, k ) );
1323 ASSERT( uIsValid(p) );
1326//-----------------------------------------------------------------------------
1327template < DGtal::Dimension dim, typename TInteger>
1329typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1330DGtal::KhalimskySpaceND< dim, TInteger>::
1331uGetAdd( const Cell & p, DGtal::Dimension k, Integer x ) const
1333 Cell cell( PreCellularGridSpace::uGetAdd( p, k, x ) );
1334 this->updateCellHelper( cell, k );
1335 ASSERT( uIsValid( cell ) );
1338//-----------------------------------------------------------------------------
1339template < DGtal::Dimension dim, typename TInteger>
1341typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1342DGtal::KhalimskySpaceND< dim, TInteger>::
1343uGetSub( const Cell & p, DGtal::Dimension k, Integer x ) const
1345 Cell cell( PreCellularGridSpace::uGetSub( p, k, x ) );
1346 this->updateCellHelper( cell, k );
1347 ASSERT( uIsValid( cell ) );
1350//-----------------------------------------------------------------------------
1351template < DGtal::Dimension dim, typename TInteger>
1354DGtal::KhalimskySpaceND< dim, TInteger>::
1355uDistanceToMax( const Cell & p, DGtal::Dimension k ) const
1357 using KPS = PreCellularGridSpace;
1359 ASSERT( uIsValid(p) );
1360 return ( KPS::uKCoord( myCellUpper, k ) - KPS::uKCoord( p, k ) ) >> 1;
1362//-----------------------------------------------------------------------------
1363template < DGtal::Dimension dim, typename TInteger>
1366DGtal::KhalimskySpaceND< dim, TInteger>::
1367uDistanceToMin( const Cell & p, DGtal::Dimension k ) const
1369 using KPS = PreCellularGridSpace;
1371 ASSERT( uIsValid(p) );
1372 return ( KPS::uKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1374//-----------------------------------------------------------------------------
1375template < DGtal::Dimension dim, typename TInteger>
1377typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1378DGtal::KhalimskySpaceND< dim, TInteger>::
1379uTranslation( const Cell & p, const Vector & vec ) const
1381 Cell cell( PreCellularGridSpace::uTranslation( p, vec ) );
1382 this->updateCellHelper( cell );
1383 ASSERT( uIsValid( cell ) );
1386//-----------------------------------------------------------------------------
1387template < DGtal::Dimension dim, typename TInteger>
1389typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1390DGtal::KhalimskySpaceND< dim, TInteger>::
1391uProjection( const Cell & p, const Cell & bound, DGtal::Dimension k ) const
1393 Cell cell( PreCellularGridSpace::uProjection( p, bound, k ) );
1394 ASSERT( uIsValid( cell ) );
1397//-----------------------------------------------------------------------------
1398template < DGtal::Dimension dim, typename TInteger>
1401DGtal::KhalimskySpaceND< dim, TInteger>::
1402uProject( Cell & p, const Cell & bound, DGtal::Dimension k ) const
1404 PreCellularGridSpace::uProject( p.myPreCell, bound, k );
1405 ASSERT( uIsValid( p ) );
1407//-----------------------------------------------------------------------------
1408template < DGtal::Dimension dim, typename TInteger>
1411DGtal::KhalimskySpaceND< dim, TInteger>::
1412uNext( Cell & p, const Cell & lower, const Cell & upper ) const
1414 ASSERT( uIsValid(p) );
1415 ASSERT( uIsValid(lower) );
1416 ASSERT( uIsValid(upper) );
1417 ASSERT( uTopology(p) == uTopology(lower)
1418 && uTopology(p) == uTopology(upper) );
1420 using KPS = PreCellularGridSpace;
1422 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1423 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1425 if ( p == upper ) return false;
1426 KPS::uProject( p.myPreCell, lower, k );
1428 for ( k = 1; k < DIM; ++k )
1430 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1431 KPS::uProject( p.myPreCell, lower, k );
1434 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1441 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1445//-----------------------------------------------------------------------------
1446///////////////////////////////////////////////////////////////////////////////
1447//-----------------------------------------------------------------------------
1448//-----------------------------------------------------------------------------
1449template < DGtal::Dimension dim, typename TInteger>
1451typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1452DGtal::KhalimskySpaceND< dim, TInteger>::
1453sFirst( const SPreCell & p, DGtal::Dimension k ) const
1457 return myClosure[ k ] == OPEN ?
1458 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1459 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1461//-----------------------------------------------------------------------------
1462template < DGtal::Dimension dim, typename TInteger>
1464typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1465DGtal::KhalimskySpaceND< dim, TInteger >::
1466sFirst( const SPreCell & p ) const
1469 for ( Dimension k = 0; k < dimension; ++k )
1470 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sFirst( p, k ) );
1472 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1476//-----------------------------------------------------------------------------
1477template < DGtal::Dimension dim, typename TInteger>
1479typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1480DGtal::KhalimskySpaceND< dim, TInteger>::
1481sLast( const SPreCell & p, DGtal::Dimension k ) const
1484 return myClosure[ k ] == CLOSED ?
1485 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1486 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1488//-----------------------------------------------------------------------------
1489template < DGtal::Dimension dim, typename TInteger>
1491typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1492DGtal::KhalimskySpaceND< dim, TInteger >::
1493sLast( const SPreCell & p ) const
1496 for ( Dimension k = 0; k < dimension; ++k )
1497 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sLast( p, k ) );
1499 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1503//-----------------------------------------------------------------------------
1504template < DGtal::Dimension dim, typename TInteger>
1506typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1507DGtal::KhalimskySpaceND< dim, TInteger >::
1508sGetIncr( const SCell & p, DGtal::Dimension k ) const
1510 SCell cell( PreCellularGridSpace::sGetIncr( p, k ) );
1511 this->updateSCellHelper( cell, k );
1512 ASSERT( sIsValid( cell ) );
1515//-----------------------------------------------------------------------------
1516template < DGtal::Dimension dim, typename TInteger>
1519DGtal::KhalimskySpaceND< dim, TInteger >::
1520sIsMax( const SCell & p, DGtal::Dimension k ) const
1523 ASSERT( sIsInside(p) );
1525 ! this->isDimensionPeriodicHelper( k )
1526 && PreCellularGridSpace::sKCoord( p, k ) >= sLast( p, k );
1528//-----------------------------------------------------------------------------
1529template < DGtal::Dimension dim, typename TInteger>
1532DGtal::KhalimskySpaceND< dim, TInteger>::
1533sIsInside( const SPreCell & p, DGtal::Dimension k ) const
1535 return cIsInside( p.coordinates, k );
1537//-----------------------------------------------------------------------------
1538template < DGtal::Dimension dim, typename TInteger>
1541DGtal::KhalimskySpaceND< dim, TInteger>::
1542sIsInside( const SPreCell & p ) const
1544 return cIsInside( p.coordinates );
1546//-----------------------------------------------------------------------------
1547template < DGtal::Dimension dim, typename TInteger>
1549typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1550DGtal::KhalimskySpaceND< dim, TInteger >::
1551sGetMax( SCell p, DGtal::Dimension k ) const
1553 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sLast( p, k ) );
1554 ASSERT( sIsValid( p ) );
1557//-----------------------------------------------------------------------------
1558template < DGtal::Dimension dim, typename TInteger>
1560typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1561DGtal::KhalimskySpaceND< dim, TInteger >::
1562sGetDecr( const SCell & p, DGtal::Dimension k ) const
1564 SCell cell( PreCellularGridSpace::sGetDecr( p, k ) );
1565 this->updateSCellHelper( cell, k );
1566 ASSERT( sIsValid( cell ) );
1569//-----------------------------------------------------------------------------
1570template < DGtal::Dimension dim, typename TInteger>
1573DGtal::KhalimskySpaceND< dim, TInteger >::
1574sIsMin( const SCell & p, DGtal::Dimension k ) const
1577 ASSERT( sIsInside(p) );
1579 ! this->isDimensionPeriodicHelper( k )
1580 && PreCellularGridSpace::sKCoord( p, k ) <= sFirst( p, k );
1582//-----------------------------------------------------------------------------
1583template < DGtal::Dimension dim, typename TInteger>
1585typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1586DGtal::KhalimskySpaceND< dim, TInteger >::
1587sGetMin( SCell p, DGtal::Dimension k ) const
1589 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sFirst( p, k ) );
1590 ASSERT( sIsValid( p ) );
1593//-----------------------------------------------------------------------------
1594template < DGtal::Dimension dim, typename TInteger>
1596typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1597DGtal::KhalimskySpaceND< dim, TInteger >::
1598sGetAdd( const SCell & p, DGtal::Dimension k, Integer x ) const
1600 SCell cell( PreCellularGridSpace::sGetAdd( p, k, x ) );
1601 this->updateSCellHelper( cell, k );
1602 ASSERT( sIsValid( cell ) );
1605//-----------------------------------------------------------------------------
1606template < DGtal::Dimension dim, typename TInteger>
1608typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1609DGtal::KhalimskySpaceND< dim, TInteger >::
1610sGetSub( const SCell & p, DGtal::Dimension k, Integer x ) const
1612 SCell cell( PreCellularGridSpace::sGetSub( p, k, x ) );
1613 this->updateSCellHelper( cell, k );
1614 ASSERT( sIsValid( cell ) );
1617//-----------------------------------------------------------------------------
1618template < DGtal::Dimension dim, typename TInteger>
1621DGtal::KhalimskySpaceND< dim, TInteger >::
1622sDistanceToMax( const SCell & p, DGtal::Dimension k ) const
1624 using KPS = PreCellularGridSpace;
1626 ASSERT( sIsValid( p ) );
1627 return ( KPS::uKCoord( myCellUpper, k ) - KPS::sKCoord( p, k ) ) >> 1;
1629//-----------------------------------------------------------------------------
1630template < DGtal::Dimension dim, typename TInteger>
1633DGtal::KhalimskySpaceND< dim, TInteger >::
1634sDistanceToMin( const SCell & p, DGtal::Dimension k ) const
1636 using KPS = PreCellularGridSpace;
1638 ASSERT( sIsValid( p ) );
1639 return ( KPS::sKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1641//-----------------------------------------------------------------------------
1642template < DGtal::Dimension dim, typename TInteger>
1644typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1645DGtal::KhalimskySpaceND< dim, TInteger >::
1646sTranslation( const SCell & p, const Vector & vec ) const
1648 SCell cell( PreCellularGridSpace::sTranslation( p, vec ) );
1649 this->updateSCellHelper( cell );
1650 ASSERT( sIsValid( cell ) );
1653//-----------------------------------------------------------------------------
1654template < DGtal::Dimension dim, typename TInteger>
1656typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1657DGtal::KhalimskySpaceND< dim, TInteger >::
1658sProjection( const SCell & p, const SCell & bound, DGtal::Dimension k ) const
1660 SCell cell( PreCellularGridSpace::sProjection( p, bound, k ) );
1661 ASSERT( sIsValid( cell ) );
1664//-----------------------------------------------------------------------------
1665template < DGtal::Dimension dim, typename TInteger>
1668DGtal::KhalimskySpaceND< dim, TInteger >::
1669sProject( SCell & p, const SCell & bound, DGtal::Dimension k ) const
1671 PreCellularGridSpace::sProject( p.mySPreCell, bound, k );
1672 ASSERT( sIsValid( p ) );
1674//-----------------------------------------------------------------------------
1675template < DGtal::Dimension dim, typename TInteger>
1678DGtal::KhalimskySpaceND< dim, TInteger >::
1679sNext( SCell & p, const SCell & lower, const SCell & upper ) const
1681 ASSERT( sIsValid(p) );
1682 ASSERT( sIsValid(lower) );
1683 ASSERT( sIsValid(upper) );
1684 ASSERT( sTopology(p) == sTopology(lower)
1685 && sTopology(p) == sTopology(upper) );
1687 using KPS = PreCellularGridSpace;
1689 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1690 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1692 if ( p == upper ) return false;
1693 KPS::sProject( p.mySPreCell, lower, k );
1695 for ( k = 1; k < DIM; ++k )
1697 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1698 KPS::sProject( p.mySPreCell, lower, k );
1701 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1708 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1712//-----------------------------------------------------------------------------
1713// ----------------------- Neighborhood services --------------------------
1714//-----------------------------------------------------------------------------
1715template < DGtal::Dimension dim, typename TInteger>
1717typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1718DGtal::KhalimskySpaceND< dim, TInteger >::
1719uNeighborhood( const Cell & c ) const
1721 ASSERT( uIsValid(c) );
1725 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1727 if ( ! uIsMin( c, k ) )
1728 N.push_back( uGetDecr( c, k ) );
1729 if ( ! uIsMax( c, k ) )
1730 N.push_back( uGetIncr( c, k ) );
1734//-----------------------------------------------------------------------------
1735template < DGtal::Dimension dim, typename TInteger>
1737typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1738DGtal::KhalimskySpaceND< dim, TInteger >::
1739sNeighborhood( const SCell & c ) const
1741 ASSERT( sIsValid(c) );
1745 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1747 if ( ! sIsMin( c, k ) )
1748 N.push_back( sGetDecr( c, k ) );
1749 if ( ! sIsMax( c, k ) )
1750 N.push_back( sGetIncr( c, k ) );
1754//-----------------------------------------------------------------------------
1755template < DGtal::Dimension dim, typename TInteger>
1757typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1758DGtal::KhalimskySpaceND< dim, TInteger >::
1759uProperNeighborhood( const Cell & c ) const
1761 ASSERT( uIsValid(c) );
1764 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1766 if ( ! uIsMin( c, k ) )
1767 N.push_back( uGetDecr( c, k ) );
1768 if ( ! uIsMax( c, k ) )
1769 N.push_back( uGetIncr( c, k ) );
1773//-----------------------------------------------------------------------------
1774template < DGtal::Dimension dim, typename TInteger>
1776typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1777DGtal::KhalimskySpaceND< dim, TInteger >::
1778sProperNeighborhood( const SCell & c ) const
1780 ASSERT( sIsValid(c) );
1783 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1785 if ( ! sIsMin( c, k ) )
1786 N.push_back( sGetDecr( c, k ) );
1787 if ( ! sIsMax( c, k ) )
1788 N.push_back( sGetIncr( c, k ) );
1792//-----------------------------------------------------------------------------
1793template < DGtal::Dimension dim, typename TInteger>
1795typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1796DGtal::KhalimskySpaceND< dim, TInteger >::
1797uAdjacent( const Cell & p, DGtal::Dimension k, bool up ) const
1800 ASSERT( uIsValid(p) );
1801 ASSERT( ( up && !uIsMax(p, k) ) || ( !up && !uIsMin(p, k) ) );
1802 return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1804//-----------------------------------------------------------------------------
1805template < DGtal::Dimension dim, typename TInteger>
1807typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1808DGtal::KhalimskySpaceND< dim, TInteger >::
1809sAdjacent( const SCell & p, DGtal::Dimension k, bool up ) const
1812 ASSERT( sIsValid(p) );
1813 ASSERT( ( up && !sIsMax(p, k) ) || ( !up && !sIsMin(p, k) ) );
1814 return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1817// ----------------------- Incidence services --------------------------
1818//-----------------------------------------------------------------------------
1819template < DGtal::Dimension dim, typename TInteger>
1821typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1822DGtal::KhalimskySpaceND< dim, TInteger >::
1823uIncident( const Cell & c, DGtal::Dimension k, bool up ) const
1826 ASSERT( uIsValid(c) );
1827 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( uKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1828 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < uKCoord( c, k ) ) );
1830 Cell cell( PreCellularGridSpace::uIncident( c, k, up ) );
1831 this->updateCellHelper( cell, k );
1835//-----------------------------------------------------------------------------
1836template < DGtal::Dimension dim, typename TInteger>
1838typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1839DGtal::KhalimskySpaceND< dim, TInteger >::
1840sIncident( const SCell & c, DGtal::Dimension k, bool up ) const
1843 ASSERT( sIsValid(c) );
1844 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( sKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1845 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < sKCoord( c, k ) ) );
1847 SCell cell( PreCellularGridSpace::sIncident( c, k, up ) );
1848 this->updateSCellHelper( cell, k );
1852//-----------------------------------------------------------------------------
1853template < DGtal::Dimension dim, typename TInteger>
1855typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1856DGtal::KhalimskySpaceND< dim, TInteger >::
1857uLowerIncident( const Cell & c ) const
1859 ASSERT( uIsValid(c) );
1862 for ( DirIterator q = uDirs( 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//-----------------------------------------------------------------------------
1882template < DGtal::Dimension dim, typename TInteger>
1884typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1885DGtal::KhalimskySpaceND< dim, TInteger >::
1886uUpperIncident( const Cell & c ) const
1888 ASSERT( uIsValid(c) );
1891 for ( DirIterator q = uOrthDirs( c ); q != 0; ++q )
1893 const DGtal::Dimension k = *q;
1894 if ( this->isDimensionPeriodicHelper( k ) )
1896 N.push_back( uIncident( c, k, false ) );
1897 N.push_back( uIncident( c, k, true ) );
1901 const Integer x = uKCoord( c, k );
1902 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1903 N.push_back( uIncident( c, k, false ) );
1904 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1905 N.push_back( uIncident( c, k, true ) );
1910//-----------------------------------------------------------------------------
1911template < DGtal::Dimension dim, typename TInteger>
1913typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1914DGtal::KhalimskySpaceND< dim, TInteger >::
1915sLowerIncident( const SCell & c ) const
1917 ASSERT( sIsValid(c) );
1920 for ( DirIterator q = sDirs( 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//-----------------------------------------------------------------------------
1940template < DGtal::Dimension dim, typename TInteger>
1942typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1943DGtal::KhalimskySpaceND< dim, TInteger >::
1944sUpperIncident( const SCell & c ) const
1946 ASSERT( sIsValid(c) );
1949 for ( DirIterator q = sOrthDirs( c ); q != 0; ++q )
1951 const DGtal::Dimension k = *q;
1952 if ( this->isDimensionPeriodicHelper( k ) )
1954 N.push_back( sIncident( c, k, false ) );
1955 N.push_back( sIncident( c, k, true ) );
1959 const Integer x = sKCoord( c, k );
1960 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1961 N.push_back( sIncident( c, k, false ) );
1962 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1963 N.push_back( sIncident( c, k, true ) );
1968//-----------------------------------------------------------------------------
1969template < DGtal::Dimension dim, typename TInteger>
1972DGtal::KhalimskySpaceND< dim, TInteger >::
1973uAddFaces( Cells& faces, const Cell& c, Dimension axis ) const
1975 using KPS = PreCellularGridSpace;
1977 const DGtal::Dimension dim_of_c = uDim( c );
1978 if ( axis >= dim_of_c ) return;
1980 DirIterator q = uDirs( c );
1981 for ( Dimension i = 0; i < axis; ++i ) ++q;
1983 // We test incident cells existence within the current Khalimsky space.
1984 const Integer x = KPS::uKCoord( c, *q );
1985 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
1986 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
1989 if ( has_f1 ) f1 = uIncident( c, *q, false );
1990 if ( has_f2 ) f2 = uIncident( c, *q, true );
1992 if ( has_f1 ) faces.push_back( f1 );
1993 if ( has_f2 ) faces.push_back( f2 );
1995 if ( has_f1 ) uAddFaces( faces, f1, axis );
1996 if ( has_f2 ) uAddFaces( faces, f2, axis );
1998 uAddFaces( faces, c, axis+1 );
2000//-----------------------------------------------------------------------------
2001template < DGtal::Dimension dim, typename TInteger>
2004DGtal::KhalimskySpaceND< dim, TInteger >::
2005uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis ) const
2007 using KPS = PreCellularGridSpace;
2009 const DGtal::Dimension dim_of_c = uDim( c );
2010 if ( axis >= dimension - dim_of_c ) return;
2012 DirIterator q = uOrthDirs( c );
2013 for ( Dimension i = 0; i < axis; ++i ) ++q;
2015 // We test incident cells existence within the current Khalimsky space.
2016 const Integer x = KPS::uKCoord( c, *q );
2017 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
2018 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
2021 if ( has_f1 ) f1 = uIncident( c, *q, false );
2022 if ( has_f2 ) f2 = uIncident( c, *q, true );
2024 if ( has_f1 ) cofaces.push_back( f1 );
2025 if ( has_f2 ) cofaces.push_back( f2 );
2027 if ( has_f1 ) uAddCoFaces( cofaces, f1, axis );
2028 if ( has_f2 ) uAddCoFaces( cofaces, f2, axis );
2030 uAddCoFaces( cofaces, c, axis+1 );
2032//-----------------------------------------------------------------------------
2033template < DGtal::Dimension dim, typename TInteger>
2035typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2036DGtal::KhalimskySpaceND< dim, TInteger >::
2037uFaces( const Cell & c ) const
2039 ASSERT( uIsValid(c) );
2042 uAddFaces( N, c, 0 );
2045//-----------------------------------------------------------------------------
2046template < DGtal::Dimension dim, typename TInteger>
2048typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2049DGtal::KhalimskySpaceND< dim, TInteger >::
2050uCoFaces( const Cell & c ) const
2052 ASSERT( uIsValid(c) );
2055 uAddCoFaces( N, c, 0 );
2058//-----------------------------------------------------------------------------
2059template < DGtal::Dimension dim, typename TInteger>
2062DGtal::KhalimskySpaceND< dim, TInteger >::
2063sDirect( const SCell & p, DGtal::Dimension k ) const
2065 return PreCellularGridSpace::sDirect( p, k );
2067//-----------------------------------------------------------------------------
2068template < DGtal::Dimension dim, typename TInteger>
2070typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2071DGtal::KhalimskySpaceND< dim, TInteger >::
2072sDirectIncident( const SCell & p, DGtal::Dimension k ) const
2074 using KPS = PreCellularGridSpace;
2077 ASSERT( sIsValid(p) );
2078 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2079 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2081 SCell cell( KPS::sDirectIncident( p, k ) );
2082 this->updateSCellHelper( cell, k );
2086//-----------------------------------------------------------------------------
2087template < DGtal::Dimension dim, typename TInteger>
2089typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2090DGtal::KhalimskySpaceND< dim, TInteger >::
2091sIndirectIncident( const SCell & p, DGtal::Dimension k ) const
2093 using KPS = PreCellularGridSpace;
2096 ASSERT( sIsValid(p) );
2097 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2098 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2100 SCell cell( KPS::sIndirectIncident( p, k ) );
2101 this->updateSCellHelper( cell, k );
2109//-----------------------------------------------------------------------------
2110template < DGtal::Dimension dim, typename TInteger>
2113DGtal::KhalimskySpaceND< dim, TInteger>::
2114selfDisplay ( std::ostream & out ) const
2116 out << "[KhalimskySpaceND<" << dimension << ">] { ";
2118 for ( Dimension i = 0; i < dimension; ++i )
2119 out << ( myClosure[i] == OPEN ? "OPEN " : ( myClosure[i] == CLOSED ? "CLOSED " : "PERIODIC " ) );
2121 out << "lower = " << myLower << ", ";
2122 out << "upper = " << myUpper;
2126//-----------------------------------------------------------------------------
2127template < DGtal::Dimension dim, typename TInteger>
2130DGtal::KhalimskySpaceND< dim, TInteger>::
2138///////////////////////////////////////////////////////////////////////////////
2139// Implementation of inline functions //
2140template < DGtal::Dimension dim, typename TInteger>
2143DGtal::operator<< ( std::ostream & out,
2144 const KhalimskySpaceND< dim, TInteger> & object )
2146 object.selfDisplay( out );
2151///////////////////////////////////////////////////////////////////////////////