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>
455DGtal::KhalimskySpaceND< dim, TInteger>::
456KhalimskySpaceND( const Point & lower,
460 init( lower, upper, isClosed );
462//-----------------------------------------------------------------------------
463template < DGtal::Dimension dim, typename TInteger>
466DGtal::KhalimskySpaceND< dim, TInteger>::
467init( const Point & lower,
471 std::array<Closure, dimension> closure;
472 for ( DGtal::Dimension i = 0; i < dimension; ++i )
473 closure[ i ] = isClosed ? CLOSED : OPEN;
475 return init( lower, upper, closure );
477//-----------------------------------------------------------------------------
478template < DGtal::Dimension dim, typename TInteger>
481DGtal::KhalimskySpaceND< dim, TInteger>::
482init( const Point & lower,
486 std::array<Closure, dimension> dimClosure;
487 dimClosure.fill( closure );
489 return init( lower, upper, dimClosure );
492//-----------------------------------------------------------------------------
493template < DGtal::Dimension dim, typename TInteger>
496DGtal::KhalimskySpaceND< dim, TInteger>::
497init( const Point & lower,
499 const std::array<Closure, dim> & closure )
505 if ( NumberTraits< Integer >::isBounded() == BOUNDED )
507 for ( DGtal::Dimension i = 0; i < dimension; ++i )
509 if ( ( lower[ i ] <= ( NumberTraits< Integer >::min() / 2 ) )
510 || ( upper[ i ] >= ( NumberTraits< Integer >::max() / 2 ) ) )
515 for ( DGtal::Dimension i = 0; i < dimension; ++i )
517 PreCellularGridSpace::uSetKCoord( myCellLower.myPreCell, i, ( lower[ i ] * 2 ) + ( closure[ i ] != OPEN ? 0 : 1 ) );
518 PreCellularGridSpace::uSetKCoord( myCellUpper.myPreCell, i, ( upper[ i ] * 2 ) + ( closure[ i ] == CLOSED ? 2 : 1 ) );
522 return this->initHelper();
524//-----------------------------------------------------------------------------
525template < DGtal::Dimension dim, typename TInteger>
527typename DGtal::KhalimskySpaceND< dim, TInteger>::Size
528DGtal::KhalimskySpaceND< dim, TInteger>::
529size( DGtal::Dimension k ) const
531 ASSERT( k < dimension );
532 return myUpper[ k ] + NumberTraits<Integer>::ONE - myLower[ k ];
534//-----------------------------------------------------------------------------
535template < DGtal::Dimension dim, typename TInteger>
538DGtal::KhalimskySpaceND< dim, TInteger>::
539min( DGtal::Dimension k ) const
543//-----------------------------------------------------------------------------
544template < DGtal::Dimension dim, typename TInteger>
547DGtal::KhalimskySpaceND< dim, TInteger>::
548max( DGtal::Dimension k ) const
552//-----------------------------------------------------------------------------
553template < DGtal::Dimension dim, typename TInteger>
555const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
556DGtal::KhalimskySpaceND< dim, TInteger>::
561//-----------------------------------------------------------------------------
562template < DGtal::Dimension dim, typename TInteger>
564const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
565DGtal::KhalimskySpaceND< dim, TInteger>::
570//-----------------------------------------------------------------------------
571template < DGtal::Dimension dim, typename TInteger>
573const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
574DGtal::KhalimskySpaceND< dim, TInteger>::
579//-----------------------------------------------------------------------------
580template < DGtal::Dimension dim, typename TInteger>
582const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
583DGtal::KhalimskySpaceND< dim, TInteger>::
588//-----------------------------------------------------------------------------
589template < DGtal::Dimension dim, typename TInteger>
592DGtal::KhalimskySpaceND< dim, TInteger>::
593uIsValid( const PreCell & p, Dimension k ) const
595 return cIsValid( p.coordinates, k );
597//-----------------------------------------------------------------------------
598template < DGtal::Dimension dim, typename TInteger>
601DGtal::KhalimskySpaceND< dim, TInteger>::
602uIsValid( const PreCell & p ) const
604 return cIsValid( p.coordinates );
606//-----------------------------------------------------------------------------
607template < DGtal::Dimension dim, typename TInteger>
610DGtal::KhalimskySpaceND< dim, TInteger>::
611cIsValid( const Point & p, Dimension k ) const
613 return p[ k ] <= PreCellularGridSpace::uKCoord( myCellUpper, k )
614 && p[ k ] >= PreCellularGridSpace::uKCoord( myCellLower, k );
616//-----------------------------------------------------------------------------
617template < DGtal::Dimension dim, typename TInteger>
620DGtal::KhalimskySpaceND< dim, TInteger>::
621cIsValid( const Point & p ) const
623 for ( Dimension k = 0; k < DIM; ++ k )
624 if ( ! cIsValid( p, k ) )
629//-----------------------------------------------------------------------------
630template < DGtal::Dimension dim, typename TInteger>
633DGtal::KhalimskySpaceND< dim, TInteger>::
634sIsValid( const SPreCell & p, Dimension k ) const
636 return cIsValid( p.coordinates, k );
638//-----------------------------------------------------------------------------
639template < DGtal::Dimension dim, typename TInteger>
642DGtal::KhalimskySpaceND< dim, TInteger>::
643sIsValid( const SPreCell & p ) const
645 return cIsValid( p.coordinates );
647//-----------------------------------------------------------------------------
648template < DGtal::Dimension dim, typename TInteger>
651DGtal::KhalimskySpaceND< dim, TInteger>::
654 for ( Dimension i = 0; i < dimension; ++i )
655 if ( myClosure[ i ] == OPEN )
660//-----------------------------------------------------------------------------
661template < DGtal::Dimension dim, typename TInteger>
664DGtal::KhalimskySpaceND< dim, TInteger>::
665isSpaceClosed( Dimension k ) const
667 return myClosure[ k ] != OPEN;
669//-----------------------------------------------------------------------------
670template < DGtal::Dimension dim, typename TInteger>
673DGtal::KhalimskySpaceND< dim, TInteger>::
674isSpacePeriodic() const
676 for ( Dimension i = 0; i < dimension; ++i )
677 if ( myClosure[ i ] != PERIODIC )
682//-----------------------------------------------------------------------------
683template < DGtal::Dimension dim, typename TInteger>
686DGtal::KhalimskySpaceND< dim, TInteger>::
687isSpacePeriodic( Dimension k ) const
689 return myClosure[ k ] == PERIODIC;
691//-----------------------------------------------------------------------------
692template < DGtal::Dimension dim, typename TInteger>
695DGtal::KhalimskySpaceND< dim, TInteger>::
696isAnyDimensionPeriodic() const
698 return this->isAnyDimensionPeriodicHelper();
700//-----------------------------------------------------------------------------
701template < DGtal::Dimension dim, typename TInteger>
703typename DGtal::KhalimskySpaceND< dim, TInteger>::Closure
704DGtal::KhalimskySpaceND< dim, TInteger>::
705getClosure(Dimension k) const
709//-----------------------------------------------------------------------------
710template < DGtal::Dimension dim, typename TInteger>
712typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
713DGtal::KhalimskySpaceND< dim, TInteger>::
714uCell( const PreCell & c ) const
716 return uCell( c.coordinates );
718//-----------------------------------------------------------------------------
719template < DGtal::Dimension dim, typename TInteger>
721typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
722DGtal::KhalimskySpaceND< dim, TInteger>::
723uCell( const Point & kp ) const
725 ASSERT( cIsInside( kp ) );
726 return Cell( this->returnKCoordsHelper( kp ) );
728//-----------------------------------------------------------------------------
729template < DGtal::Dimension dim, typename TInteger>
731typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
732DGtal::KhalimskySpaceND< dim, TInteger>::
733uCell( Point p, const PreCell & c ) const
735 return uCell( PreCellularGridSpace::uCell( p, c ) );
737//-----------------------------------------------------------------------------
738template < DGtal::Dimension dim, typename TInteger>
740typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
741DGtal::KhalimskySpaceND< dim, TInteger>::
742sCell( const SPreCell & c ) const
744 return sCell( c.coordinates, c.positive ? POS : NEG );
746//-----------------------------------------------------------------------------
747template < DGtal::Dimension dim, typename TInteger>
749typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
750DGtal::KhalimskySpaceND< dim, TInteger>::
751sCell( const Point & kp, Sign sign ) const
753 ASSERT( cIsInside( kp ) );
754 return SCell( this->returnKCoordsHelper( kp ), sign == POS );
756//-----------------------------------------------------------------------------
757template < DGtal::Dimension dim, typename TInteger>
759typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
760DGtal::KhalimskySpaceND< dim, TInteger>::
761sCell( Point p, const SPreCell & c ) const
763 return sCell( PreCellularGridSpace::sCell( p, c ) );
765//-----------------------------------------------------------------------------
766template < DGtal::Dimension dim, typename TInteger>
768typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
769DGtal::KhalimskySpaceND< dim, TInteger>::
770uSpel( Point p ) const
772 return uCell( PreCellularGridSpace::uSpel( p ) );
774//-----------------------------------------------------------------------------
775template < DGtal::Dimension dim, typename TInteger>
777typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
778DGtal::KhalimskySpaceND< dim, TInteger>::
779sSpel( Point p, Sign sign ) const
781 return sCell( PreCellularGridSpace::sSpel( p, sign ) );
783//-----------------------------------------------------------------------------
784template < DGtal::Dimension dim, typename TInteger>
786typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
787DGtal::KhalimskySpaceND< dim, TInteger>::
788uPointel( Point p ) const
790 return uCell( PreCellularGridSpace::uPointel( p ) );
792//-----------------------------------------------------------------------------
793template < DGtal::Dimension dim, typename TInteger>
795typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
796DGtal::KhalimskySpaceND< dim, TInteger>::
797sPointel( Point p, Sign sign ) const
799 return sCell( PreCellularGridSpace::sPointel( p, sign ) );
801//-----------------------------------------------------------------------------
802///////////////////////////////////////////////////////////////////////////////
803//-----------------------------------------------------------------------------
804template < DGtal::Dimension dim, typename TInteger>
806typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
807DGtal::KhalimskySpaceND< dim, TInteger>::
808uKCoord( const Cell & c, DGtal::Dimension k ) const
810 ASSERT( uIsValid(c) );
811 return PreCellularGridSpace::uKCoord( c, k );
813//-----------------------------------------------------------------------------
814template < DGtal::Dimension dim, typename TInteger>
816typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
817DGtal::KhalimskySpaceND< dim, TInteger>::
818uCoord( const Cell & c, DGtal::Dimension k ) const
820 ASSERT( uIsValid(c) );
821 return PreCellularGridSpace::uCoord( c, k );
823//-----------------------------------------------------------------------------
824template < DGtal::Dimension dim, typename TInteger>
826typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
827DGtal::KhalimskySpaceND< dim, TInteger>::
828uKCoords( const Cell & c ) const
830 ASSERT( uIsValid(c) );
831 return PreCellularGridSpace::uKCoords( c );
833//-----------------------------------------------------------------------------
834template < DGtal::Dimension dim, typename TInteger>
836typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
837DGtal::KhalimskySpaceND< dim, TInteger>::
838uCoords( const Cell & c ) const
840 ASSERT( uIsValid(c) );
841 return PreCellularGridSpace::uCoords( c );
843//-----------------------------------------------------------------------------
844template < DGtal::Dimension dim, typename TInteger>
846typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
847DGtal::KhalimskySpaceND< dim, TInteger>::
848interiorVoxel( const SCell & sc ) const
850 ASSERT( sIsValid(sc) );
851 return PreCellularGridSpace::interiorVoxel( sc );
853//-----------------------------------------------------------------------------
854template < DGtal::Dimension dim, typename TInteger>
856typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
857DGtal::KhalimskySpaceND< dim, TInteger>::
858exteriorVoxel( const SCell & sc ) const
860 ASSERT( sIsValid(sc) );
861 return PreCellularGridSpace::exteriorVoxel( sc );
863//-----------------------------------------------------------------------------
864template < DGtal::Dimension dim, typename TInteger>
866typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
867DGtal::KhalimskySpaceND< dim, TInteger>::
868sKCoord( const SCell & c, DGtal::Dimension k ) const
870 ASSERT( sIsValid(c) );
871 return PreCellularGridSpace::sKCoord( c, k );
873//-----------------------------------------------------------------------------
874template < DGtal::Dimension dim, typename TInteger>
876typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
877DGtal::KhalimskySpaceND< dim, TInteger>::
878sCoord( const SCell & c, DGtal::Dimension k ) const
880 ASSERT( sIsValid(c) );
881 return PreCellularGridSpace::sCoord( c, k );
883//-----------------------------------------------------------------------------
884template < DGtal::Dimension dim, typename TInteger>
886typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
887DGtal::KhalimskySpaceND< dim, TInteger>::
888sKCoords( const SCell & c ) const
890 ASSERT( sIsValid(c) );
891 return PreCellularGridSpace::sKCoords( c );
893//-----------------------------------------------------------------------------
894template < DGtal::Dimension dim, typename TInteger>
896typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
897DGtal::KhalimskySpaceND< dim, TInteger>::
898sCoords( const SCell & c ) const
900 ASSERT( sIsValid(c) );
901 return PreCellularGridSpace::sCoords( c );
903//-----------------------------------------------------------------------------
904template < DGtal::Dimension dim, typename TInteger>
906typename DGtal::KhalimskySpaceND< dim, TInteger>::Sign
907DGtal::KhalimskySpaceND< dim, TInteger>::
908sSign( const SCell & c ) const
910 ASSERT( sIsValid(c) );
911 return PreCellularGridSpace::sSign( c );
913//-----------------------------------------------------------------------------
914template < DGtal::Dimension dim, typename TInteger>
916typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
917DGtal::KhalimskySpaceND< dim, TInteger>::
918signs( const Cell & p, Sign s ) const
920 return sCell( PreCellularGridSpace::signs( p, s ) );
922//-----------------------------------------------------------------------------
923template < DGtal::Dimension dim, typename TInteger>
925typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
926DGtal::KhalimskySpaceND< dim, TInteger>::
927unsigns( const SCell & p ) const
929 return uCell( PreCellularGridSpace::unsigns( p ) );
931//-----------------------------------------------------------------------------
932template < DGtal::Dimension dim, typename TInteger>
934typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
935DGtal::KhalimskySpaceND< dim, TInteger>::
936sOpp( const SCell & p ) const
938 return sCell( PreCellularGridSpace::sOpp( p ) );
940//-----------------------------------------------------------------------------
941template < DGtal::Dimension dim, typename TInteger>
944DGtal::KhalimskySpaceND< dim, TInteger>::
945uSetKCoord( Cell & c, DGtal::Dimension k, Integer i ) const
947 PreCellularGridSpace::uSetKCoord( c.myPreCell, k, i );
948 this->updateCellHelper( c, k );
949 ASSERT( uIsValid(c) );
951//-----------------------------------------------------------------------------
952template < DGtal::Dimension dim, typename TInteger>
955DGtal::KhalimskySpaceND< dim, TInteger>::
956sSetKCoord( SCell & c, DGtal::Dimension k, Integer i ) const
958 PreCellularGridSpace::sSetKCoord( c.mySPreCell, k, i );
959 this->updateSCellHelper( c, k );
960 ASSERT( sIsValid(c) );
962//-----------------------------------------------------------------------------
963template < DGtal::Dimension dim, typename TInteger>
966DGtal::KhalimskySpaceND< dim, TInteger>::
967uSetCoord( Cell & c, DGtal::Dimension k, Integer i ) const
969 PreCellularGridSpace::uSetCoord( c.myPreCell, k, i );
970 this->updateCellHelper( c, k );
971 ASSERT( uIsValid(c) );
973//-----------------------------------------------------------------------------
974template < DGtal::Dimension dim, typename TInteger>
977DGtal::KhalimskySpaceND< dim, TInteger>::
978sSetCoord( SCell & c, DGtal::Dimension k, Integer i ) const
980 PreCellularGridSpace::sSetCoord( c.mySPreCell, k, i );
981 this->updateSCellHelper( c, k );
982 ASSERT( sIsValid(c) );
984//-----------------------------------------------------------------------------
985template < DGtal::Dimension dim, typename TInteger>
988DGtal::KhalimskySpaceND< dim, TInteger>::
989uSetKCoords( Cell & c, const Point & kp ) const
991 PreCellularGridSpace::uSetKCoords( c.myPreCell, kp );
992 this->updateCellHelper( c );
993 ASSERT( uIsValid(c) );
995//-----------------------------------------------------------------------------
996template < DGtal::Dimension dim, typename TInteger>
999DGtal::KhalimskySpaceND< dim, TInteger>::
1000sSetKCoords( SCell & c, const Point & kp ) const
1002 PreCellularGridSpace::sSetKCoords( c.mySPreCell, kp );
1003 this->updateSCellHelper( c );
1004 ASSERT( sIsValid(c) );
1006//-----------------------------------------------------------------------------
1007template < DGtal::Dimension dim, typename TInteger>
1010DGtal::KhalimskySpaceND< dim, TInteger>::
1011uSetCoords( Cell & c, const Point & p ) const
1013 PreCellularGridSpace::uSetCoords( c.myPreCell, p );
1014 this->updateCellHelper( c );
1015 ASSERT( uIsValid(c) );
1017//-----------------------------------------------------------------------------
1018template < DGtal::Dimension dim, typename TInteger>
1021DGtal::KhalimskySpaceND< dim, TInteger>::
1022sSetCoords( SCell & c, const Point & p ) const
1024 PreCellularGridSpace::sSetCoords( c.mySPreCell, p );
1025 this->updateSCellHelper( c );
1026 ASSERT( sIsValid(c) );
1028//-----------------------------------------------------------------------------
1029template < DGtal::Dimension dim, typename TInteger>
1032DGtal::KhalimskySpaceND< dim, TInteger>::
1033sSetSign( SCell & c, Sign s ) const
1035 PreCellularGridSpace::sSetSign( c.mySPreCell, s );
1037//-----------------------------------------------------------------------------
1038// ------------------------- Cell topology services -----------------------
1039//-----------------------------------------------------------------------------
1040template < DGtal::Dimension dim, typename TInteger>
1043DGtal::KhalimskySpaceND< dim, TInteger>::
1044uTopology( const Cell & p ) const
1046 return PreCellularGridSpace::uTopology( p );
1048//-----------------------------------------------------------------------------
1049template < DGtal::Dimension dim, typename TInteger>
1052DGtal::KhalimskySpaceND< dim, TInteger>::
1053sTopology( const SCell & p ) const
1055 return PreCellularGridSpace::sTopology( p );
1057//-----------------------------------------------------------------------------
1058template < DGtal::Dimension dim, typename TInteger>
1061DGtal::KhalimskySpaceND< dim, TInteger>::
1062uDim( const Cell & p ) const
1064 return PreCellularGridSpace::uDim( p );
1066//-----------------------------------------------------------------------------
1067template < DGtal::Dimension dim, typename TInteger>
1070DGtal::KhalimskySpaceND< dim, TInteger>::
1071sDim( const SCell & p ) const
1073 return PreCellularGridSpace::sDim( p );
1075//-----------------------------------------------------------------------------
1076template < DGtal::Dimension dim, typename TInteger>
1079DGtal::KhalimskySpaceND< dim, TInteger>::
1080uIsSurfel( const Cell & b ) const
1082 return PreCellularGridSpace::uIsSurfel( b );
1084//-----------------------------------------------------------------------------
1085template < DGtal::Dimension dim, typename TInteger>
1088DGtal::KhalimskySpaceND< dim, TInteger>::
1089sIsSurfel( const SCell & b ) const
1091 return PreCellularGridSpace::sIsSurfel( b );
1093//-----------------------------------------------------------------------------
1094template < DGtal::Dimension dim, typename TInteger>
1097DGtal::KhalimskySpaceND< dim, TInteger>::
1098uIsOpen( const Cell & p, DGtal::Dimension k ) const
1100 return PreCellularGridSpace::uIsOpen( p, k );
1102//-----------------------------------------------------------------------------
1103template < DGtal::Dimension dim, typename TInteger>
1106DGtal::KhalimskySpaceND< dim, TInteger>::
1107sIsOpen( const SCell & p, DGtal::Dimension k ) const
1109 return PreCellularGridSpace::sIsOpen( p, k );
1112//-----------------------------------------------------------------------------
1113///////////////////////////////////////////////////////////////////////////////
1114//-----------------------------------------------------------------------------
1115template < DGtal::Dimension dim, typename TInteger>
1117typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1118DGtal::KhalimskySpaceND< dim, TInteger>::
1119uDirs( const Cell & p ) const
1121 return PreCellularGridSpace::uDirs( p );
1123//-----------------------------------------------------------------------------
1124template < DGtal::Dimension dim, typename TInteger>
1126typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1127DGtal::KhalimskySpaceND< dim, TInteger>::
1128sDirs( const SCell & p ) const
1130 return PreCellularGridSpace::sDirs( p );
1132//-----------------------------------------------------------------------------
1133template < DGtal::Dimension dim, typename TInteger>
1135typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1136DGtal::KhalimskySpaceND< dim, TInteger>::
1137uOrthDirs( const Cell & p ) const
1139 return PreCellularGridSpace::uOrthDirs( p );
1141//-----------------------------------------------------------------------------
1142template < DGtal::Dimension dim, typename TInteger>
1144typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1145DGtal::KhalimskySpaceND< dim, TInteger>::
1146sOrthDirs( const SCell & p ) const
1148 return PreCellularGridSpace::sOrthDirs( p );
1150//-----------------------------------------------------------------------------
1151template < DGtal::Dimension dim, typename TInteger>
1154DGtal::KhalimskySpaceND< dim, TInteger>::
1155uOrthDir( const Cell & s ) const
1157 return PreCellularGridSpace::uOrthDir( s );
1159//-----------------------------------------------------------------------------
1160template < DGtal::Dimension dim, typename TInteger>
1163DGtal::KhalimskySpaceND< dim, TInteger>::
1164sOrthDir( const SCell & s ) const
1166 return PreCellularGridSpace::sOrthDir( s );
1168//-----------------------------------------------------------------------------
1169///////////////////////////////////////////////////////////////////////////////
1170//-----------------------------------------------------------------------------
1171//-----------------------------------------------------------------------------
1172template < DGtal::Dimension dim, typename TInteger>
1174typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1175DGtal::KhalimskySpaceND< dim, TInteger>::
1176uFirst( const PreCell & p, DGtal::Dimension k ) const
1180 return myClosure[ k ] == OPEN ?
1181 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1182 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1184//-----------------------------------------------------------------------------
1185template < DGtal::Dimension dim, typename TInteger>
1187typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1188DGtal::KhalimskySpaceND< dim, TInteger>::
1189uFirst( const PreCell & p ) const
1192 for ( Dimension k = 0; k < dimension; ++k )
1193 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uFirst( p, k ) );
1197//-----------------------------------------------------------------------------
1198template < DGtal::Dimension dim, typename TInteger>
1200typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1201DGtal::KhalimskySpaceND< dim, TInteger>::
1202uLast( const PreCell & p, DGtal::Dimension k ) const
1206 return myClosure[ k ] == CLOSED ?
1207 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1208 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1210//-----------------------------------------------------------------------------
1211template < DGtal::Dimension dim, typename TInteger>
1213typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1214DGtal::KhalimskySpaceND< dim, TInteger>::
1215uLast( const PreCell & p ) const
1218 for ( Dimension k = 0; k < dimension; ++k )
1219 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uLast( p, k ) );
1223//-----------------------------------------------------------------------------
1224template < DGtal::Dimension dim, typename TInteger>
1226typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1227DGtal::KhalimskySpaceND< dim, TInteger>::
1228uGetIncr( const Cell & p, DGtal::Dimension k ) const
1230 Cell cell( PreCellularGridSpace::uGetIncr( p, k ) );
1231 this->updateCellHelper( cell, k );
1232 ASSERT( uIsValid(cell) );
1235//-----------------------------------------------------------------------------
1236template < DGtal::Dimension dim, typename TInteger>
1239DGtal::KhalimskySpaceND< dim, TInteger>::
1240uIsMax( const Cell & p, DGtal::Dimension k ) const
1243 ASSERT( uIsInside(p) );
1245 ! this->isDimensionPeriodicHelper( k )
1246 && PreCellularGridSpace::uKCoord( p, k ) >= uLast( p, k );
1248//-----------------------------------------------------------------------------
1249template < DGtal::Dimension dim, typename TInteger>
1252DGtal::KhalimskySpaceND< dim, TInteger>::
1253uIsInside( const PreCell & p, DGtal::Dimension k ) const
1255 return cIsInside( p.coordinates, k );
1257//-----------------------------------------------------------------------------
1258template < DGtal::Dimension dim, typename TInteger>
1261DGtal::KhalimskySpaceND< dim, TInteger>::
1262uIsInside( const PreCell & p ) const
1264 return cIsInside( p.coordinates );
1266//-----------------------------------------------------------------------------
1267template < DGtal::Dimension dim, typename TInteger>
1270DGtal::KhalimskySpaceND< dim, TInteger>::
1271cIsInside( const Point & p, DGtal::Dimension k ) const
1274 return this->isDimensionPeriodicHelper( k )
1275 || cIsValid( p, k );
1277//-----------------------------------------------------------------------------
1278template < DGtal::Dimension dim, typename TInteger>
1281DGtal::KhalimskySpaceND< dim, TInteger>::
1282cIsInside( const Point & p ) const
1284 for ( Dimension k = 0; k < DIM; ++k )
1285 if ( ! cIsInside( p, k ) )
1290//-----------------------------------------------------------------------------
1291template < DGtal::Dimension dim, typename TInteger>
1293typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1294DGtal::KhalimskySpaceND< dim, TInteger>::
1295uGetMax( Cell p, DGtal::Dimension k ) const
1297 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uLast( p, k ) );
1298 ASSERT( uIsValid( p ) );
1301//-----------------------------------------------------------------------------
1302template < DGtal::Dimension dim, typename TInteger>
1304typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1305DGtal::KhalimskySpaceND< dim, TInteger>::
1306uGetDecr( const Cell & p, DGtal::Dimension k ) const
1308 Cell cell( PreCellularGridSpace::uGetDecr( p, k ) );
1309 this->updateCellHelper( cell, k );
1310 ASSERT( uIsValid( cell ) );
1313//-----------------------------------------------------------------------------
1314template < DGtal::Dimension dim, typename TInteger>
1317DGtal::KhalimskySpaceND< dim, TInteger>::
1318uIsMin( const Cell & p, DGtal::Dimension k ) const
1320 ASSERT( uIsInside(p) );
1322 ! this->isDimensionPeriodicHelper( k )
1323 && PreCellularGridSpace::uKCoord( p, k ) <= uFirst( p, k );
1325//-----------------------------------------------------------------------------
1326template < DGtal::Dimension dim, typename TInteger>
1328typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1329DGtal::KhalimskySpaceND< dim, TInteger>::
1330uGetMin( Cell p, DGtal::Dimension k ) const
1332 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uFirst( p, k ) );
1333 ASSERT( uIsValid(p) );
1336//-----------------------------------------------------------------------------
1337template < DGtal::Dimension dim, typename TInteger>
1339typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1340DGtal::KhalimskySpaceND< dim, TInteger>::
1341uGetAdd( const Cell & p, DGtal::Dimension k, Integer x ) const
1343 Cell cell( PreCellularGridSpace::uGetAdd( p, k, x ) );
1344 this->updateCellHelper( cell, k );
1345 ASSERT( uIsValid( cell ) );
1348//-----------------------------------------------------------------------------
1349template < DGtal::Dimension dim, typename TInteger>
1351typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1352DGtal::KhalimskySpaceND< dim, TInteger>::
1353uGetSub( const Cell & p, DGtal::Dimension k, Integer x ) const
1355 Cell cell( PreCellularGridSpace::uGetSub( p, k, x ) );
1356 this->updateCellHelper( cell, k );
1357 ASSERT( uIsValid( cell ) );
1360//-----------------------------------------------------------------------------
1361template < DGtal::Dimension dim, typename TInteger>
1364DGtal::KhalimskySpaceND< dim, TInteger>::
1365uDistanceToMax( const Cell & p, DGtal::Dimension k ) const
1367 using KPS = PreCellularGridSpace;
1369 ASSERT( uIsValid(p) );
1370 return ( KPS::uKCoord( myCellUpper, k ) - KPS::uKCoord( p, k ) ) >> 1;
1372//-----------------------------------------------------------------------------
1373template < DGtal::Dimension dim, typename TInteger>
1376DGtal::KhalimskySpaceND< dim, TInteger>::
1377uDistanceToMin( const Cell & p, DGtal::Dimension k ) const
1379 using KPS = PreCellularGridSpace;
1381 ASSERT( uIsValid(p) );
1382 return ( KPS::uKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1384//-----------------------------------------------------------------------------
1385template < DGtal::Dimension dim, typename TInteger>
1387typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1388DGtal::KhalimskySpaceND< dim, TInteger>::
1389uTranslation( const Cell & p, const Vector & vec ) const
1391 Cell cell( PreCellularGridSpace::uTranslation( p, vec ) );
1392 this->updateCellHelper( cell );
1393 ASSERT( uIsValid( cell ) );
1396//-----------------------------------------------------------------------------
1397template < DGtal::Dimension dim, typename TInteger>
1399typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1400DGtal::KhalimskySpaceND< dim, TInteger>::
1401uProjection( const Cell & p, const Cell & bound, DGtal::Dimension k ) const
1403 Cell cell( PreCellularGridSpace::uProjection( p, bound, k ) );
1404 ASSERT( uIsValid( cell ) );
1407//-----------------------------------------------------------------------------
1408template < DGtal::Dimension dim, typename TInteger>
1411DGtal::KhalimskySpaceND< dim, TInteger>::
1412uProject( Cell & p, const Cell & bound, DGtal::Dimension k ) const
1414 PreCellularGridSpace::uProject( p.myPreCell, bound, k );
1415 ASSERT( uIsValid( p ) );
1417//-----------------------------------------------------------------------------
1418template < DGtal::Dimension dim, typename TInteger>
1421DGtal::KhalimskySpaceND< dim, TInteger>::
1422uNext( Cell & p, const Cell & lower, const Cell & upper ) const
1424 ASSERT( uIsValid(p) );
1425 ASSERT( uIsValid(lower) );
1426 ASSERT( uIsValid(upper) );
1427 ASSERT( uTopology(p) == uTopology(lower)
1428 && uTopology(p) == uTopology(upper) );
1430 using KPS = PreCellularGridSpace;
1432 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1433 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1435 if ( p == upper ) return false;
1436 KPS::uProject( p.myPreCell, lower, k );
1438 for ( k = 1; k < DIM; ++k )
1440 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1441 KPS::uProject( p.myPreCell, lower, k );
1444 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1451 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1455//-----------------------------------------------------------------------------
1456///////////////////////////////////////////////////////////////////////////////
1457//-----------------------------------------------------------------------------
1458//-----------------------------------------------------------------------------
1459template < DGtal::Dimension dim, typename TInteger>
1461typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1462DGtal::KhalimskySpaceND< dim, TInteger>::
1463sFirst( const SPreCell & p, DGtal::Dimension k ) const
1467 return myClosure[ k ] == OPEN ?
1468 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1469 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1471//-----------------------------------------------------------------------------
1472template < DGtal::Dimension dim, typename TInteger>
1474typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1475DGtal::KhalimskySpaceND< dim, TInteger >::
1476sFirst( const SPreCell & p ) const
1479 for ( Dimension k = 0; k < dimension; ++k )
1480 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sFirst( p, k ) );
1482 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1486//-----------------------------------------------------------------------------
1487template < DGtal::Dimension dim, typename TInteger>
1489typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1490DGtal::KhalimskySpaceND< dim, TInteger>::
1491sLast( const SPreCell & p, DGtal::Dimension k ) const
1494 return myClosure[ k ] == CLOSED ?
1495 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1496 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1498//-----------------------------------------------------------------------------
1499template < DGtal::Dimension dim, typename TInteger>
1501typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1502DGtal::KhalimskySpaceND< dim, TInteger >::
1503sLast( const SPreCell & p ) const
1506 for ( Dimension k = 0; k < dimension; ++k )
1507 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sLast( p, k ) );
1509 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1513//-----------------------------------------------------------------------------
1514template < DGtal::Dimension dim, typename TInteger>
1516typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1517DGtal::KhalimskySpaceND< dim, TInteger >::
1518sGetIncr( const SCell & p, DGtal::Dimension k ) const
1520 SCell cell( PreCellularGridSpace::sGetIncr( p, k ) );
1521 this->updateSCellHelper( cell, k );
1522 ASSERT( sIsValid( cell ) );
1525//-----------------------------------------------------------------------------
1526template < DGtal::Dimension dim, typename TInteger>
1529DGtal::KhalimskySpaceND< dim, TInteger >::
1530sIsMax( const SCell & p, DGtal::Dimension k ) const
1533 ASSERT( sIsInside(p) );
1535 ! this->isDimensionPeriodicHelper( k )
1536 && PreCellularGridSpace::sKCoord( p, k ) >= sLast( p, k );
1538//-----------------------------------------------------------------------------
1539template < DGtal::Dimension dim, typename TInteger>
1542DGtal::KhalimskySpaceND< dim, TInteger>::
1543sIsInside( const SPreCell & p, DGtal::Dimension k ) const
1545 return cIsInside( p.coordinates, k );
1547//-----------------------------------------------------------------------------
1548template < DGtal::Dimension dim, typename TInteger>
1551DGtal::KhalimskySpaceND< dim, TInteger>::
1552sIsInside( const SPreCell & p ) const
1554 return cIsInside( p.coordinates );
1556//-----------------------------------------------------------------------------
1557template < DGtal::Dimension dim, typename TInteger>
1559typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1560DGtal::KhalimskySpaceND< dim, TInteger >::
1561sGetMax( SCell p, DGtal::Dimension k ) const
1563 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sLast( p, k ) );
1564 ASSERT( sIsValid( p ) );
1567//-----------------------------------------------------------------------------
1568template < DGtal::Dimension dim, typename TInteger>
1570typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1571DGtal::KhalimskySpaceND< dim, TInteger >::
1572sGetDecr( const SCell & p, DGtal::Dimension k ) const
1574 SCell cell( PreCellularGridSpace::sGetDecr( p, k ) );
1575 this->updateSCellHelper( cell, k );
1576 ASSERT( sIsValid( cell ) );
1579//-----------------------------------------------------------------------------
1580template < DGtal::Dimension dim, typename TInteger>
1583DGtal::KhalimskySpaceND< dim, TInteger >::
1584sIsMin( const SCell & p, DGtal::Dimension k ) const
1587 ASSERT( sIsInside(p) );
1589 ! this->isDimensionPeriodicHelper( k )
1590 && PreCellularGridSpace::sKCoord( p, k ) <= sFirst( p, k );
1592//-----------------------------------------------------------------------------
1593template < DGtal::Dimension dim, typename TInteger>
1595typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1596DGtal::KhalimskySpaceND< dim, TInteger >::
1597sGetMin( SCell p, DGtal::Dimension k ) const
1599 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sFirst( p, k ) );
1600 ASSERT( sIsValid( p ) );
1603//-----------------------------------------------------------------------------
1604template < DGtal::Dimension dim, typename TInteger>
1606typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1607DGtal::KhalimskySpaceND< dim, TInteger >::
1608sGetAdd( const SCell & p, DGtal::Dimension k, Integer x ) const
1610 SCell cell( PreCellularGridSpace::sGetAdd( p, k, x ) );
1611 this->updateSCellHelper( cell, k );
1612 ASSERT( sIsValid( cell ) );
1615//-----------------------------------------------------------------------------
1616template < DGtal::Dimension dim, typename TInteger>
1618typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1619DGtal::KhalimskySpaceND< dim, TInteger >::
1620sGetSub( const SCell & p, DGtal::Dimension k, Integer x ) const
1622 SCell cell( PreCellularGridSpace::sGetSub( p, k, x ) );
1623 this->updateSCellHelper( cell, k );
1624 ASSERT( sIsValid( cell ) );
1627//-----------------------------------------------------------------------------
1628template < DGtal::Dimension dim, typename TInteger>
1631DGtal::KhalimskySpaceND< dim, TInteger >::
1632sDistanceToMax( const SCell & p, DGtal::Dimension k ) const
1634 using KPS = PreCellularGridSpace;
1636 ASSERT( sIsValid( p ) );
1637 return ( KPS::uKCoord( myCellUpper, k ) - KPS::sKCoord( p, k ) ) >> 1;
1639//-----------------------------------------------------------------------------
1640template < DGtal::Dimension dim, typename TInteger>
1643DGtal::KhalimskySpaceND< dim, TInteger >::
1644sDistanceToMin( const SCell & p, DGtal::Dimension k ) const
1646 using KPS = PreCellularGridSpace;
1648 ASSERT( sIsValid( p ) );
1649 return ( KPS::sKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1651//-----------------------------------------------------------------------------
1652template < DGtal::Dimension dim, typename TInteger>
1654typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1655DGtal::KhalimskySpaceND< dim, TInteger >::
1656sTranslation( const SCell & p, const Vector & vec ) const
1658 SCell cell( PreCellularGridSpace::sTranslation( p, vec ) );
1659 this->updateSCellHelper( cell );
1660 ASSERT( sIsValid( cell ) );
1663//-----------------------------------------------------------------------------
1664template < DGtal::Dimension dim, typename TInteger>
1666typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1667DGtal::KhalimskySpaceND< dim, TInteger >::
1668sProjection( const SCell & p, const SCell & bound, DGtal::Dimension k ) const
1670 SCell cell( PreCellularGridSpace::sProjection( p, bound, k ) );
1671 ASSERT( sIsValid( cell ) );
1674//-----------------------------------------------------------------------------
1675template < DGtal::Dimension dim, typename TInteger>
1678DGtal::KhalimskySpaceND< dim, TInteger >::
1679sProject( SCell & p, const SCell & bound, DGtal::Dimension k ) const
1681 PreCellularGridSpace::sProject( p.mySPreCell, bound, k );
1682 ASSERT( sIsValid( p ) );
1684//-----------------------------------------------------------------------------
1685template < DGtal::Dimension dim, typename TInteger>
1688DGtal::KhalimskySpaceND< dim, TInteger >::
1689sNext( SCell & p, const SCell & lower, const SCell & upper ) const
1691 ASSERT( sIsValid(p) );
1692 ASSERT( sIsValid(lower) );
1693 ASSERT( sIsValid(upper) );
1694 ASSERT( sTopology(p) == sTopology(lower)
1695 && sTopology(p) == sTopology(upper) );
1697 using KPS = PreCellularGridSpace;
1699 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1700 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1702 if ( p == upper ) return false;
1703 KPS::sProject( p.mySPreCell, lower, k );
1705 for ( k = 1; k < DIM; ++k )
1707 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1708 KPS::sProject( p.mySPreCell, lower, k );
1711 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1718 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1722//-----------------------------------------------------------------------------
1723// ----------------------- Neighborhood services --------------------------
1724//-----------------------------------------------------------------------------
1725template < DGtal::Dimension dim, typename TInteger>
1727typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1728DGtal::KhalimskySpaceND< dim, TInteger >::
1729uNeighborhood( const Cell & c ) const
1731 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//-----------------------------------------------------------------------------
1745template < DGtal::Dimension dim, typename TInteger>
1747typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1748DGtal::KhalimskySpaceND< dim, TInteger >::
1749sNeighborhood( const SCell & c ) const
1751 ASSERT( sIsValid(c) );
1755 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1757 if ( ! sIsMin( c, k ) )
1758 N.push_back( sGetDecr( c, k ) );
1759 if ( ! sIsMax( c, k ) )
1760 N.push_back( sGetIncr( c, k ) );
1764//-----------------------------------------------------------------------------
1765template < DGtal::Dimension dim, typename TInteger>
1767typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1768DGtal::KhalimskySpaceND< dim, TInteger >::
1769uProperNeighborhood( const Cell & c ) const
1771 ASSERT( uIsValid(c) );
1774 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1776 if ( ! uIsMin( c, k ) )
1777 N.push_back( uGetDecr( c, k ) );
1778 if ( ! uIsMax( c, k ) )
1779 N.push_back( uGetIncr( c, k ) );
1783//-----------------------------------------------------------------------------
1784template < DGtal::Dimension dim, typename TInteger>
1786typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1787DGtal::KhalimskySpaceND< dim, TInteger >::
1788sProperNeighborhood( const SCell & c ) const
1790 ASSERT( sIsValid(c) );
1793 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1795 if ( ! sIsMin( c, k ) )
1796 N.push_back( sGetDecr( c, k ) );
1797 if ( ! sIsMax( c, k ) )
1798 N.push_back( sGetIncr( c, k ) );
1802//-----------------------------------------------------------------------------
1803template < DGtal::Dimension dim, typename TInteger>
1805typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1806DGtal::KhalimskySpaceND< dim, TInteger >::
1807uAdjacent( const Cell & p, DGtal::Dimension k, bool up ) const
1810 ASSERT( uIsValid(p) );
1811 ASSERT( ( up && !uIsMax(p, k) ) || ( !up && !uIsMin(p, k) ) );
1812 return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1814//-----------------------------------------------------------------------------
1815template < DGtal::Dimension dim, typename TInteger>
1817typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1818DGtal::KhalimskySpaceND< dim, TInteger >::
1819sAdjacent( const SCell & p, DGtal::Dimension k, bool up ) const
1822 ASSERT( sIsValid(p) );
1823 ASSERT( ( up && !sIsMax(p, k) ) || ( !up && !sIsMin(p, k) ) );
1824 return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1827// ----------------------- Incidence services --------------------------
1828//-----------------------------------------------------------------------------
1829template < DGtal::Dimension dim, typename TInteger>
1831typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1832DGtal::KhalimskySpaceND< dim, TInteger >::
1833uIncident( const Cell & c, DGtal::Dimension k, bool up ) const
1836 ASSERT( uIsValid(c) );
1837 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( uKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1838 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < uKCoord( c, k ) ) );
1840 Cell cell( PreCellularGridSpace::uIncident( c, k, up ) );
1841 this->updateCellHelper( cell, k );
1845//-----------------------------------------------------------------------------
1846template < DGtal::Dimension dim, typename TInteger>
1848typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1849DGtal::KhalimskySpaceND< dim, TInteger >::
1850sIncident( const SCell & c, DGtal::Dimension k, bool up ) const
1853 ASSERT( sIsValid(c) );
1854 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( sKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1855 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < sKCoord( c, k ) ) );
1857 SCell cell( PreCellularGridSpace::sIncident( c, k, up ) );
1858 this->updateSCellHelper( cell, k );
1862//-----------------------------------------------------------------------------
1863template < DGtal::Dimension dim, typename TInteger>
1865typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1866DGtal::KhalimskySpaceND< dim, TInteger >::
1867uLowerIncident( const Cell & c ) const
1869 ASSERT( uIsValid(c) );
1872 for ( DirIterator q = uDirs( c ); q != 0; ++q )
1874 const DGtal::Dimension k = *q;
1875 if ( this->isDimensionPeriodicHelper( k ) )
1877 N.push_back( uIncident( c, k, false ) );
1878 N.push_back( uIncident( c, k, true ) );
1882 const Integer x = uKCoord( c, k );
1883 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1884 N.push_back( uIncident( c, k, false ) );
1885 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1886 N.push_back( uIncident( c, k, true ) );
1891//-----------------------------------------------------------------------------
1892template < DGtal::Dimension dim, typename TInteger>
1894typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1895DGtal::KhalimskySpaceND< dim, TInteger >::
1896uUpperIncident( const Cell & c ) const
1898 ASSERT( uIsValid(c) );
1901 for ( DirIterator q = uOrthDirs( c ); q != 0; ++q )
1903 const DGtal::Dimension k = *q;
1904 if ( this->isDimensionPeriodicHelper( k ) )
1906 N.push_back( uIncident( c, k, false ) );
1907 N.push_back( uIncident( c, k, true ) );
1911 const Integer x = uKCoord( c, k );
1912 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1913 N.push_back( uIncident( c, k, false ) );
1914 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1915 N.push_back( uIncident( c, k, true ) );
1920//-----------------------------------------------------------------------------
1921template < DGtal::Dimension dim, typename TInteger>
1923typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1924DGtal::KhalimskySpaceND< dim, TInteger >::
1925sLowerIncident( const SCell & c ) const
1927 ASSERT( sIsValid(c) );
1930 for ( DirIterator q = sDirs( c ); q != 0; ++q )
1932 const DGtal::Dimension k = *q;
1933 if ( this->isDimensionPeriodicHelper( k ) )
1935 N.push_back( sIncident( c, k, false ) );
1936 N.push_back( sIncident( c, k, true ) );
1940 const Integer x = sKCoord( c, k );
1941 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1942 N.push_back( sIncident( c, k, false ) );
1943 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1944 N.push_back( sIncident( c, k, true ) );
1949//-----------------------------------------------------------------------------
1950template < DGtal::Dimension dim, typename TInteger>
1952typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1953DGtal::KhalimskySpaceND< dim, TInteger >::
1954sUpperIncident( const SCell & c ) const
1956 ASSERT( sIsValid(c) );
1959 for ( DirIterator q = sOrthDirs( c ); q != 0; ++q )
1961 const DGtal::Dimension k = *q;
1962 if ( this->isDimensionPeriodicHelper( k ) )
1964 N.push_back( sIncident( c, k, false ) );
1965 N.push_back( sIncident( c, k, true ) );
1969 const Integer x = sKCoord( c, k );
1970 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1971 N.push_back( sIncident( c, k, false ) );
1972 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1973 N.push_back( sIncident( c, k, true ) );
1978//-----------------------------------------------------------------------------
1979template < DGtal::Dimension dim, typename TInteger>
1982DGtal::KhalimskySpaceND< dim, TInteger >::
1983uAddFaces( Cells& faces, const Cell& c, Dimension axis ) const
1985 using KPS = PreCellularGridSpace;
1987 const DGtal::Dimension dim_of_c = uDim( c );
1988 if ( axis >= dim_of_c ) return;
1990 DirIterator q = uDirs( c );
1991 for ( Dimension i = 0; i < axis; ++i ) ++q;
1993 // We test incident cells existence within the current Khalimsky space.
1994 const Integer x = KPS::uKCoord( c, *q );
1995 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
1996 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
1999 if ( has_f1 ) f1 = uIncident( c, *q, false );
2000 if ( has_f2 ) f2 = uIncident( c, *q, true );
2002 if ( has_f1 ) faces.push_back( f1 );
2003 if ( has_f2 ) faces.push_back( f2 );
2005 if ( has_f1 ) uAddFaces( faces, f1, axis );
2006 if ( has_f2 ) uAddFaces( faces, f2, axis );
2008 uAddFaces( faces, c, axis+1 );
2010//-----------------------------------------------------------------------------
2011template < DGtal::Dimension dim, typename TInteger>
2014DGtal::KhalimskySpaceND< dim, TInteger >::
2015uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis ) const
2017 using KPS = PreCellularGridSpace;
2019 const DGtal::Dimension dim_of_c = uDim( c );
2020 if ( axis >= dimension - dim_of_c ) return;
2022 DirIterator q = uOrthDirs( c );
2023 for ( Dimension i = 0; i < axis; ++i ) ++q;
2025 // We test incident cells existence within the current Khalimsky space.
2026 const Integer x = KPS::uKCoord( c, *q );
2027 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
2028 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
2031 if ( has_f1 ) f1 = uIncident( c, *q, false );
2032 if ( has_f2 ) f2 = uIncident( c, *q, true );
2034 if ( has_f1 ) cofaces.push_back( f1 );
2035 if ( has_f2 ) cofaces.push_back( f2 );
2037 if ( has_f1 ) uAddCoFaces( cofaces, f1, axis );
2038 if ( has_f2 ) uAddCoFaces( cofaces, f2, axis );
2040 uAddCoFaces( cofaces, c, axis+1 );
2042//-----------------------------------------------------------------------------
2043template < DGtal::Dimension dim, typename TInteger>
2045typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2046DGtal::KhalimskySpaceND< dim, TInteger >::
2047uFaces( const Cell & c ) const
2049 ASSERT( uIsValid(c) );
2052 uAddFaces( N, c, 0 );
2055//-----------------------------------------------------------------------------
2056template < DGtal::Dimension dim, typename TInteger>
2058typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2059DGtal::KhalimskySpaceND< dim, TInteger >::
2060uCoFaces( const Cell & c ) const
2062 ASSERT( uIsValid(c) );
2065 uAddCoFaces( N, c, 0 );
2068//-----------------------------------------------------------------------------
2069template < DGtal::Dimension dim, typename TInteger>
2072DGtal::KhalimskySpaceND< dim, TInteger >::
2073sDirect( const SCell & p, DGtal::Dimension k ) const
2075 return PreCellularGridSpace::sDirect( p, k );
2077//-----------------------------------------------------------------------------
2078template < DGtal::Dimension dim, typename TInteger>
2080typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2081DGtal::KhalimskySpaceND< dim, TInteger >::
2082sDirectIncident( const SCell & p, DGtal::Dimension k ) const
2084 using KPS = PreCellularGridSpace;
2087 ASSERT( sIsValid(p) );
2088 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2089 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2091 SCell cell( KPS::sDirectIncident( p, k ) );
2092 this->updateSCellHelper( cell, k );
2096//-----------------------------------------------------------------------------
2097template < DGtal::Dimension dim, typename TInteger>
2099typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2100DGtal::KhalimskySpaceND< dim, TInteger >::
2101sIndirectIncident( const SCell & p, DGtal::Dimension k ) const
2103 using KPS = PreCellularGridSpace;
2106 ASSERT( sIsValid(p) );
2107 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2108 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2110 SCell cell( KPS::sIndirectIncident( p, k ) );
2111 this->updateSCellHelper( cell, k );
2119//-----------------------------------------------------------------------------
2120template < DGtal::Dimension dim, typename TInteger>
2123DGtal::KhalimskySpaceND< dim, TInteger>::
2124selfDisplay ( std::ostream & out ) const
2126 out << "[KhalimskySpaceND<" << dimension << ">] { ";
2128 for ( Dimension i = 0; i < dimension; ++i )
2129 out << ( myClosure[i] == OPEN ? "OPEN " : ( myClosure[i] == CLOSED ? "CLOSED " : "PERIODIC " ) );
2131 out << "lower = " << myLower << ", ";
2132 out << "upper = " << myUpper;
2136//-----------------------------------------------------------------------------
2137template < DGtal::Dimension dim, typename TInteger>
2140DGtal::KhalimskySpaceND< dim, TInteger>::
2148///////////////////////////////////////////////////////////////////////////////
2149// Implementation of inline functions //
2150template < DGtal::Dimension dim, typename TInteger>
2153DGtal::operator<< ( std::ostream & out,
2154 const KhalimskySpaceND< dim, TInteger> & object )
2156 object.selfDisplay( out );
2161///////////////////////////////////////////////////////////////////////////////