2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file KhalimskySpaceND.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in KhalimskySpaceND.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
31 #include <DGtal/io/Color.h>
32 #include <DGtal/kernel/NumberTraits.h>
33 //////////////////////////////////////////////////////////////////////////////
35 ///////////////////////////////////////////////////////////////////////////////
36 // Namescape scope definition of static constants.
37 ///////////////////////////////////////////////////////////////////////////////
39 template < DGtal::Dimension dim, typename TInteger >
42 DGtal::KhalimskySpaceND<dim, TInteger>::dimension;
44 template < DGtal::Dimension dim, typename TInteger >
47 DGtal::KhalimskySpaceND<dim, TInteger>::DIM;
49 template < DGtal::Dimension dim, typename TInteger >
51 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
52 DGtal::KhalimskySpaceND<dim, TInteger>::POS;
54 template < DGtal::Dimension dim, typename TInteger >
56 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
57 DGtal::KhalimskySpaceND<dim, TInteger>::NEG;
59 ///////////////////////////////////////////////////////////////////////////////
60 // IMPLEMENTATION of inline methods.
61 ///////////////////////////////////////////////////////////////////////////////
63 ///////////////////////////////////////////////////////////////////////////////
65 ///////////////////////////////////////////////////////////////////////////////
66 //-----------------------------------------------------------------------------
67 template < DGtal::Dimension dim, typename TInteger >
69 DGtal::KhalimskyCell< dim, TInteger >::
70 KhalimskyCell( Integer )
74 //-----------------------------------------------------------------------------
75 template < DGtal::Dimension dim, typename TInteger >
77 DGtal::KhalimskyCell< dim, TInteger >::
78 KhalimskyCell( const Point & p )
82 //-----------------------------------------------------------------------------
83 template < DGtal::Dimension dim, typename TInteger >
85 DGtal::KhalimskyCell< dim, TInteger >::
86 KhalimskyCell( const PreCell & aCell )
90 //-----------------------------------------------------------------------------
91 template < DGtal::Dimension dim, typename TInteger >
93 DGtal::KhalimskyCell< dim, TInteger >::
94 operator DGtal::KhalimskyPreCell< dim, TInteger > const& () const
98 //-----------------------------------------------------------------------------
99 template < DGtal::Dimension dim, typename TInteger >
101 DGtal::KhalimskyPreCell< dim, TInteger > const &
102 DGtal::KhalimskyCell< dim, TInteger >::
107 //-----------------------------------------------------------------------------
108 template < DGtal::Dimension dim, typename TInteger >
110 DGtal::KhalimskyCell< dim, TInteger >::
111 operator DGtal::KhalimskyPreCell< dim, TInteger > & ()
115 //-----------------------------------------------------------------------------
116 template < DGtal::Dimension dim, typename TInteger >
119 DGtal::KhalimskyCell< dim, TInteger >::
120 operator==( const KhalimskyCell & other ) const
122 return myPreCell == other.myPreCell;
124 //-----------------------------------------------------------------------------
125 template < DGtal::Dimension dim, typename TInteger >
128 DGtal::KhalimskyCell< dim, TInteger >::
129 operator!=( const KhalimskyCell & other ) const
131 return myPreCell != other.myPreCell;
133 //-----------------------------------------------------------------------------
134 template < DGtal::Dimension dim, typename TInteger >
137 DGtal::KhalimskyCell< dim, TInteger >::
138 operator<( const KhalimskyCell & other ) const
140 return myPreCell < other.myPreCell;
142 //-----------------------------------------------------------------------------
143 template < DGtal::Dimension dim, typename TInteger >
146 DGtal::operator<<( std::ostream & out,
147 const KhalimskyCell< dim, TInteger > & object )
149 out << static_cast< const KhalimskyPreCell<dim, TInteger> & >(object);
153 //------------------------------------------------------------------------------
154 template < DGtal::Dimension dim, typename TInteger >
157 DGtal::KhalimskyCell<dim, TInteger>::
160 return "KhalimskyCell";
163 ///////////////////////////////////////////////////////////////////////////////
164 // SignedKhalimskyCell
165 ///////////////////////////////////////////////////////////////////////////////
166 //-----------------------------------------------------------------------------
167 template < DGtal::Dimension dim, typename TInteger >
169 DGtal::SignedKhalimskyCell< dim, TInteger >::
170 SignedKhalimskyCell( Integer )
174 //-----------------------------------------------------------------------------
175 template < DGtal::Dimension dim, typename TInteger >
177 DGtal::SignedKhalimskyCell< dim, TInteger >::
178 SignedKhalimskyCell( const Point & p, bool positive )
179 : mySPreCell( p, positive )
182 //-----------------------------------------------------------------------------
183 template < DGtal::Dimension dim, typename TInteger >
185 DGtal::SignedKhalimskyCell< dim, TInteger >::
186 SignedKhalimskyCell( const SPreCell & aCell )
187 : mySPreCell( aCell )
190 //-----------------------------------------------------------------------------
191 template < DGtal::Dimension dim, typename TInteger >
193 DGtal::SignedKhalimskyCell< dim, TInteger >::
194 operator DGtal::SignedKhalimskyPreCell< dim, TInteger > const& () const
198 //-----------------------------------------------------------------------------
199 template < DGtal::Dimension dim, typename TInteger >
201 DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
202 DGtal::SignedKhalimskyCell< dim, TInteger >::
207 //-----------------------------------------------------------------------------
208 template < DGtal::Dimension dim, typename TInteger >
210 DGtal::SignedKhalimskyCell< dim, TInteger >::
211 operator DGtal::SignedKhalimskyPreCell< dim, TInteger > & ()
215 //-----------------------------------------------------------------------------
216 template < DGtal::Dimension dim, typename TInteger >
219 DGtal::SignedKhalimskyCell< dim, TInteger >::
220 operator==( const SignedKhalimskyCell & other ) const
222 return mySPreCell == other.mySPreCell;
224 //-----------------------------------------------------------------------------
225 template < DGtal::Dimension dim, typename TInteger >
228 DGtal::SignedKhalimskyCell< dim, TInteger >::
229 operator!=( const SignedKhalimskyCell & other ) const
231 return mySPreCell != other.mySPreCell;
233 //-----------------------------------------------------------------------------
234 template < DGtal::Dimension dim, typename TInteger >
237 DGtal::SignedKhalimskyCell< dim, TInteger >::
238 operator<( const SignedKhalimskyCell & other ) const
240 return mySPreCell < other.mySPreCell;
242 //-----------------------------------------------------------------------------
243 template < DGtal::Dimension dim,
247 DGtal::operator<<( std::ostream & out,
248 const SignedKhalimskyCell< dim, TInteger > & object )
250 out << static_cast< const SignedKhalimskyPreCell<dim, TInteger> & >(object);
254 //------------------------------------------------------------------------------
255 template < DGtal::Dimension dim, typename TInteger >
258 DGtal::SignedKhalimskyCell<dim, TInteger>::
261 return "SignedKhalimskyCell";
264 ///////////////////////////////////////////////////////////////////////////////
265 // KhalimskySpaceNDHelper
266 ///////////////////////////////////////////////////////////////////////////////
271 DGtal::Dimension dim,
274 class KhalimskySpaceNDHelper< KhalimskySpaceND< dim, TInteger > >
278 using KhalimskySpace = KhalimskySpaceND< dim, TInteger >;
279 using Point = PointVector< dim, TInteger >;
280 using Cell = KhalimskyCell< dim, TInteger >;
281 using SCell = SignedKhalimskyCell< dim, TInteger >;
283 /// Returns derived mutable instance
284 KhalimskySpace& derived()
286 return *static_cast<KhalimskySpace*>(this);
289 /// Returns derived constant instance
290 KhalimskySpace const & derived() const
292 return *static_cast<KhalimskySpace const*>(this);
299 /// @return true is the specified dimension is periodic
301 bool isDimensionPeriodicHelper( DGtal::Dimension d ) const
303 return derived().myClosure[ d ] == KhalimskySpace::PERIODIC;
306 /// @return true is there is at least one periodic dimension.
308 bool isAnyDimensionPeriodicHelper() const
310 return myIsAnyDimensionPeriodic;
313 /** Modifies a khalimsky coordinate according to the dimension periodicity.
314 * @param[in,out] aKCoord the coordinate to modify.
315 * @param d the coordinate dimension.
318 void updateKCoordHelper( typename Point::Coordinate & aKCoord, DGtal::Dimension d ) const
320 if ( isDimensionPeriodicHelper( d ) )
322 aKCoord = ( aKCoord - derived().myCellLower.myPreCell.coordinates[ d ] ) % myCellExtent[ d ];
323 aKCoord += ( ( aKCoord < 0 ) ?
324 derived().myCellUpper.myPreCell.coordinates[ d ] + 1
325 : derived().myCellLower.myPreCell.coordinates[ d ]
330 /** Returns a given khalimsky coordinate modified according to the dimension periodicity.
331 * @param[in] aKCoord the coordinate to modify.
332 * @param d the coordinate dimension.
333 * @returns the modified coordinate.
336 typename Point::Coordinate returnKCoordHelper( typename Point::Coordinate aKCoord, DGtal::Dimension d ) const
338 updateKCoordHelper( aKCoord, d );
342 /** Modifies khalimsky coordinates of a point according to the dimension periodicity.
343 * @param[in,out] aKCoords the khalimksy coordinates.
346 void updateKCoordsHelper( Point & aKCoords ) const
348 if ( isAnyDimensionPeriodicHelper() )
350 for ( DGtal::Dimension i = 0; i < dim; ++i )
351 updateKCoordHelper( aKCoords[ i ], i );
355 /** Returns given khalimsky coordinates of a point modified according to the dimension periodicity.
356 * @param[in] aKCoords the khalimksy coordinates.
359 Point returnKCoordsHelper( Point aKCoords ) const
361 updateKCoordsHelper( aKCoords );
365 /** Modifies a cell's khalimsky coordinate according to the dimension periodicity.
366 * @param[in,out] aCell an unsigned cell.
367 * @param d the coordinate dimension.
370 void updateCellHelper( Cell & aCell, DGtal::Dimension d ) const
372 updateKCoordHelper( aCell.myPreCell.coordinates[ d ], d );
375 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
376 * @param[in,out] aCell an unsigned cell.
379 void updateCellHelper( Cell & aCell ) const
381 updateKCoordsHelper( aCell.myPreCell.coordinates );
384 /** Modifies a cell's khalimsky coordinate according to the dimension periodicity.
385 * @param[in,out] aCell a signed cell.
386 * @param d the coordinate dimension.
389 void updateSCellHelper( SCell & aCell, DGtal::Dimension d ) const
391 updateKCoordHelper( aCell.mySPreCell.coordinates[ d ], d );
394 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
395 * @param[in,out] aCell a signed cell.
398 void updateSCellHelper( SCell & aCell ) const
400 updateKCoordsHelper( aCell.mySPreCell.coordinates );
407 myIsAnyDimensionPeriodic = false;
408 for ( DGtal::Dimension i = 0; i < dim; ++i )
410 myIsAnyDimensionPeriodic |= isDimensionPeriodicHelper( i );
411 myCellExtent[ i ] = derived().myCellUpper.myPreCell.coordinates[ i ] - derived().myCellLower.myPreCell.coordinates[ i ] + 1;
420 Point myCellExtent; ///< Extent between the extremal cells.
421 bool myIsAnyDimensionPeriodic; ///< true if there is at least one periodic dimension.
426 ///////////////////////////////////////////////////////////////////////////////
428 ///////////////////////////////////////////////////////////////////////////////
429 ///////////////////////////////////////////////////////////////////////////////
430 // ----------------------- Standard services ------------------------------
431 //-----------------------------------------------------------------------------
432 template < DGtal::Dimension dim, typename TInteger>
434 DGtal::KhalimskySpaceND< dim, TInteger>::
438 //-----------------------------------------------------------------------------
439 template < DGtal::Dimension dim, typename TInteger>
441 DGtal::KhalimskySpaceND< dim, TInteger>::
445 for ( DGtal::Dimension i = 0; i < dimension; ++i )
447 low[ i ] = NumberTraits< Integer >::min() / 2 + 1;
448 high[ i ] = NumberTraits< Integer >::max() / 2 - 1;
450 init( low, high, true );
452 //-----------------------------------------------------------------------------
453 template < DGtal::Dimension dim, typename TInteger>
455 DGtal::KhalimskySpaceND< dim, TInteger>::
456 KhalimskySpaceND( const Point & lower,
460 init( lower, upper, isClosed );
462 //-----------------------------------------------------------------------------
463 template < DGtal::Dimension dim, typename TInteger>
466 DGtal::KhalimskySpaceND< dim, TInteger>::
467 init( 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 //-----------------------------------------------------------------------------
478 template < DGtal::Dimension dim, typename TInteger>
481 DGtal::KhalimskySpaceND< dim, TInteger>::
482 init( const Point & lower,
486 std::array<Closure, dimension> dimClosure;
487 dimClosure.fill( closure );
489 return init( lower, upper, dimClosure );
492 //-----------------------------------------------------------------------------
493 template < DGtal::Dimension dim, typename TInteger>
496 DGtal::KhalimskySpaceND< dim, TInteger>::
497 init( 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 //-----------------------------------------------------------------------------
525 template < DGtal::Dimension dim, typename TInteger>
527 typename DGtal::KhalimskySpaceND< dim, TInteger>::Size
528 DGtal::KhalimskySpaceND< dim, TInteger>::
529 size( DGtal::Dimension k ) const
531 ASSERT( k < dimension );
532 return myUpper[ k ] + NumberTraits<Integer>::ONE - myLower[ k ];
534 //-----------------------------------------------------------------------------
535 template < DGtal::Dimension dim, typename TInteger>
538 DGtal::KhalimskySpaceND< dim, TInteger>::
539 min( DGtal::Dimension k ) const
543 //-----------------------------------------------------------------------------
544 template < DGtal::Dimension dim, typename TInteger>
547 DGtal::KhalimskySpaceND< dim, TInteger>::
548 max( DGtal::Dimension k ) const
552 //-----------------------------------------------------------------------------
553 template < DGtal::Dimension dim, typename TInteger>
555 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
556 DGtal::KhalimskySpaceND< dim, TInteger>::
561 //-----------------------------------------------------------------------------
562 template < DGtal::Dimension dim, typename TInteger>
564 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
565 DGtal::KhalimskySpaceND< dim, TInteger>::
570 //-----------------------------------------------------------------------------
571 template < DGtal::Dimension dim, typename TInteger>
573 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
574 DGtal::KhalimskySpaceND< dim, TInteger>::
579 //-----------------------------------------------------------------------------
580 template < DGtal::Dimension dim, typename TInteger>
582 const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
583 DGtal::KhalimskySpaceND< dim, TInteger>::
588 //-----------------------------------------------------------------------------
589 template < DGtal::Dimension dim, typename TInteger>
592 DGtal::KhalimskySpaceND< dim, TInteger>::
593 uIsValid( const PreCell & p, Dimension k ) const
595 return cIsValid( p.coordinates, k );
597 //-----------------------------------------------------------------------------
598 template < DGtal::Dimension dim, typename TInteger>
601 DGtal::KhalimskySpaceND< dim, TInteger>::
602 uIsValid( const PreCell & p ) const
604 return cIsValid( p.coordinates );
606 //-----------------------------------------------------------------------------
607 template < DGtal::Dimension dim, typename TInteger>
610 DGtal::KhalimskySpaceND< dim, TInteger>::
611 cIsValid( const Point & p, Dimension k ) const
613 return p[ k ] <= PreCellularGridSpace::uKCoord( myCellUpper, k )
614 && p[ k ] >= PreCellularGridSpace::uKCoord( myCellLower, k );
616 //-----------------------------------------------------------------------------
617 template < DGtal::Dimension dim, typename TInteger>
620 DGtal::KhalimskySpaceND< dim, TInteger>::
621 cIsValid( const Point & p ) const
623 for ( Dimension k = 0; k < DIM; ++ k )
624 if ( ! cIsValid( p, k ) )
629 //-----------------------------------------------------------------------------
630 template < DGtal::Dimension dim, typename TInteger>
633 DGtal::KhalimskySpaceND< dim, TInteger>::
634 sIsValid( const SPreCell & p, Dimension k ) const
636 return cIsValid( p.coordinates, k );
638 //-----------------------------------------------------------------------------
639 template < DGtal::Dimension dim, typename TInteger>
642 DGtal::KhalimskySpaceND< dim, TInteger>::
643 sIsValid( const SPreCell & p ) const
645 return cIsValid( p.coordinates );
647 //-----------------------------------------------------------------------------
648 template < DGtal::Dimension dim, typename TInteger>
651 DGtal::KhalimskySpaceND< dim, TInteger>::
652 isSpaceClosed() const
654 for ( Dimension i = 0; i < dimension; ++i )
655 if ( myClosure[ i ] == OPEN )
660 //-----------------------------------------------------------------------------
661 template < DGtal::Dimension dim, typename TInteger>
664 DGtal::KhalimskySpaceND< dim, TInteger>::
665 isSpaceClosed( Dimension k ) const
667 return myClosure[ k ] != OPEN;
669 //-----------------------------------------------------------------------------
670 template < DGtal::Dimension dim, typename TInteger>
673 DGtal::KhalimskySpaceND< dim, TInteger>::
674 isSpacePeriodic() const
676 for ( Dimension i = 0; i < dimension; ++i )
677 if ( myClosure[ i ] != PERIODIC )
682 //-----------------------------------------------------------------------------
683 template < DGtal::Dimension dim, typename TInteger>
686 DGtal::KhalimskySpaceND< dim, TInteger>::
687 isSpacePeriodic( Dimension k ) const
689 return myClosure[ k ] == PERIODIC;
691 //-----------------------------------------------------------------------------
692 template < DGtal::Dimension dim, typename TInteger>
695 DGtal::KhalimskySpaceND< dim, TInteger>::
696 isAnyDimensionPeriodic() const
698 return this->isAnyDimensionPeriodicHelper();
700 //-----------------------------------------------------------------------------
701 template < DGtal::Dimension dim, typename TInteger>
703 typename DGtal::KhalimskySpaceND< dim, TInteger>::Closure
704 DGtal::KhalimskySpaceND< dim, TInteger>::
705 getClosure(Dimension k) const
709 //-----------------------------------------------------------------------------
710 template < DGtal::Dimension dim, typename TInteger>
712 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
713 DGtal::KhalimskySpaceND< dim, TInteger>::
714 uCell( const PreCell & c ) const
716 return uCell( c.coordinates );
718 //-----------------------------------------------------------------------------
719 template < DGtal::Dimension dim, typename TInteger>
721 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
722 DGtal::KhalimskySpaceND< dim, TInteger>::
723 uCell( const Point & kp ) const
725 ASSERT( cIsInside( kp ) );
726 return Cell( this->returnKCoordsHelper( kp ) );
728 //-----------------------------------------------------------------------------
729 template < DGtal::Dimension dim, typename TInteger>
731 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
732 DGtal::KhalimskySpaceND< dim, TInteger>::
733 uCell( Point p, const PreCell & c ) const
735 return uCell( PreCellularGridSpace::uCell( p, c ) );
737 //-----------------------------------------------------------------------------
738 template < DGtal::Dimension dim, typename TInteger>
740 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
741 DGtal::KhalimskySpaceND< dim, TInteger>::
742 sCell( const SPreCell & c ) const
744 return sCell( c.coordinates, c.positive ? POS : NEG );
746 //-----------------------------------------------------------------------------
747 template < DGtal::Dimension dim, typename TInteger>
749 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
750 DGtal::KhalimskySpaceND< dim, TInteger>::
751 sCell( const Point & kp, Sign sign ) const
753 ASSERT( cIsInside( kp ) );
754 return SCell( this->returnKCoordsHelper( kp ), sign == POS );
756 //-----------------------------------------------------------------------------
757 template < DGtal::Dimension dim, typename TInteger>
759 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
760 DGtal::KhalimskySpaceND< dim, TInteger>::
761 sCell( Point p, const SPreCell & c ) const
763 return sCell( PreCellularGridSpace::sCell( p, c ) );
765 //-----------------------------------------------------------------------------
766 template < DGtal::Dimension dim, typename TInteger>
768 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
769 DGtal::KhalimskySpaceND< dim, TInteger>::
770 uSpel( Point p ) const
772 return uCell( PreCellularGridSpace::uSpel( p ) );
774 //-----------------------------------------------------------------------------
775 template < DGtal::Dimension dim, typename TInteger>
777 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
778 DGtal::KhalimskySpaceND< dim, TInteger>::
779 sSpel( Point p, Sign sign ) const
781 return sCell( PreCellularGridSpace::sSpel( p, sign ) );
783 //-----------------------------------------------------------------------------
784 template < DGtal::Dimension dim, typename TInteger>
786 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
787 DGtal::KhalimskySpaceND< dim, TInteger>::
788 uPointel( Point p ) const
790 return uCell( PreCellularGridSpace::uPointel( p ) );
792 //-----------------------------------------------------------------------------
793 template < DGtal::Dimension dim, typename TInteger>
795 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
796 DGtal::KhalimskySpaceND< dim, TInteger>::
797 sPointel( Point p, Sign sign ) const
799 return sCell( PreCellularGridSpace::sPointel( p, sign ) );
801 //-----------------------------------------------------------------------------
802 ///////////////////////////////////////////////////////////////////////////////
803 //-----------------------------------------------------------------------------
804 template < DGtal::Dimension dim, typename TInteger>
806 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
807 DGtal::KhalimskySpaceND< dim, TInteger>::
808 uKCoord( const Cell & c, DGtal::Dimension k ) const
810 ASSERT( uIsValid(c) );
811 return PreCellularGridSpace::uKCoord( c, k );
813 //-----------------------------------------------------------------------------
814 template < DGtal::Dimension dim, typename TInteger>
816 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
817 DGtal::KhalimskySpaceND< dim, TInteger>::
818 uCoord( const Cell & c, DGtal::Dimension k ) const
820 ASSERT( uIsValid(c) );
821 return PreCellularGridSpace::uCoord( c, k );
823 //-----------------------------------------------------------------------------
824 template < DGtal::Dimension dim, typename TInteger>
826 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
827 DGtal::KhalimskySpaceND< dim, TInteger>::
828 uKCoords( const Cell & c ) const
830 ASSERT( uIsValid(c) );
831 return PreCellularGridSpace::uKCoords( c );
833 //-----------------------------------------------------------------------------
834 template < DGtal::Dimension dim, typename TInteger>
836 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
837 DGtal::KhalimskySpaceND< dim, TInteger>::
838 uCoords( const Cell & c ) const
840 ASSERT( uIsValid(c) );
841 return PreCellularGridSpace::uCoords( c );
843 //-----------------------------------------------------------------------------
844 template < DGtal::Dimension dim, typename TInteger>
846 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
847 DGtal::KhalimskySpaceND< dim, TInteger>::
848 interiorVoxel( const SCell & sc ) const
850 ASSERT( sIsValid(sc) );
851 return PreCellularGridSpace::interiorVoxel( sc );
853 //-----------------------------------------------------------------------------
854 template < DGtal::Dimension dim, typename TInteger>
856 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
857 DGtal::KhalimskySpaceND< dim, TInteger>::
858 exteriorVoxel( const SCell & sc ) const
860 ASSERT( sIsValid(sc) );
861 return PreCellularGridSpace::exteriorVoxel( sc );
863 //-----------------------------------------------------------------------------
864 template < DGtal::Dimension dim, typename TInteger>
866 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
867 DGtal::KhalimskySpaceND< dim, TInteger>::
868 sKCoord( const SCell & c, DGtal::Dimension k ) const
870 ASSERT( sIsValid(c) );
871 return PreCellularGridSpace::sKCoord( c, k );
873 //-----------------------------------------------------------------------------
874 template < DGtal::Dimension dim, typename TInteger>
876 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
877 DGtal::KhalimskySpaceND< dim, TInteger>::
878 sCoord( const SCell & c, DGtal::Dimension k ) const
880 ASSERT( sIsValid(c) );
881 return PreCellularGridSpace::sCoord( c, k );
883 //-----------------------------------------------------------------------------
884 template < DGtal::Dimension dim, typename TInteger>
886 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
887 DGtal::KhalimskySpaceND< dim, TInteger>::
888 sKCoords( const SCell & c ) const
890 ASSERT( sIsValid(c) );
891 return PreCellularGridSpace::sKCoords( c );
893 //-----------------------------------------------------------------------------
894 template < DGtal::Dimension dim, typename TInteger>
896 typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
897 DGtal::KhalimskySpaceND< dim, TInteger>::
898 sCoords( const SCell & c ) const
900 ASSERT( sIsValid(c) );
901 return PreCellularGridSpace::sCoords( c );
903 //-----------------------------------------------------------------------------
904 template < DGtal::Dimension dim, typename TInteger>
906 typename DGtal::KhalimskySpaceND< dim, TInteger>::Sign
907 DGtal::KhalimskySpaceND< dim, TInteger>::
908 sSign( const SCell & c ) const
910 ASSERT( sIsValid(c) );
911 return PreCellularGridSpace::sSign( c );
913 //-----------------------------------------------------------------------------
914 template < DGtal::Dimension dim, typename TInteger>
916 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
917 DGtal::KhalimskySpaceND< dim, TInteger>::
918 signs( const Cell & p, Sign s ) const
920 return sCell( PreCellularGridSpace::signs( p, s ) );
922 //-----------------------------------------------------------------------------
923 template < DGtal::Dimension dim, typename TInteger>
925 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
926 DGtal::KhalimskySpaceND< dim, TInteger>::
927 unsigns( const SCell & p ) const
929 return uCell( PreCellularGridSpace::unsigns( p ) );
931 //-----------------------------------------------------------------------------
932 template < DGtal::Dimension dim, typename TInteger>
934 typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
935 DGtal::KhalimskySpaceND< dim, TInteger>::
936 sOpp( const SCell & p ) const
938 return sCell( PreCellularGridSpace::sOpp( p ) );
940 //-----------------------------------------------------------------------------
941 template < DGtal::Dimension dim, typename TInteger>
944 DGtal::KhalimskySpaceND< dim, TInteger>::
945 uSetKCoord( 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 //-----------------------------------------------------------------------------
952 template < DGtal::Dimension dim, typename TInteger>
955 DGtal::KhalimskySpaceND< dim, TInteger>::
956 sSetKCoord( 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 //-----------------------------------------------------------------------------
963 template < DGtal::Dimension dim, typename TInteger>
966 DGtal::KhalimskySpaceND< dim, TInteger>::
967 uSetCoord( 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 //-----------------------------------------------------------------------------
974 template < DGtal::Dimension dim, typename TInteger>
977 DGtal::KhalimskySpaceND< dim, TInteger>::
978 sSetCoord( 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 //-----------------------------------------------------------------------------
985 template < DGtal::Dimension dim, typename TInteger>
988 DGtal::KhalimskySpaceND< dim, TInteger>::
989 uSetKCoords( Cell & c, const Point & kp ) const
991 PreCellularGridSpace::uSetKCoords( c.myPreCell, kp );
992 this->updateCellHelper( c );
993 ASSERT( uIsValid(c) );
995 //-----------------------------------------------------------------------------
996 template < DGtal::Dimension dim, typename TInteger>
999 DGtal::KhalimskySpaceND< dim, TInteger>::
1000 sSetKCoords( SCell & c, const Point & kp ) const
1002 PreCellularGridSpace::sSetKCoords( c.mySPreCell, kp );
1003 this->updateSCellHelper( c );
1004 ASSERT( sIsValid(c) );
1006 //-----------------------------------------------------------------------------
1007 template < DGtal::Dimension dim, typename TInteger>
1010 DGtal::KhalimskySpaceND< dim, TInteger>::
1011 uSetCoords( Cell & c, const Point & p ) const
1013 PreCellularGridSpace::uSetCoords( c.myPreCell, p );
1014 this->updateCellHelper( c );
1015 ASSERT( uIsValid(c) );
1017 //-----------------------------------------------------------------------------
1018 template < DGtal::Dimension dim, typename TInteger>
1021 DGtal::KhalimskySpaceND< dim, TInteger>::
1022 sSetCoords( SCell & c, const Point & p ) const
1024 PreCellularGridSpace::sSetCoords( c.mySPreCell, p );
1025 this->updateSCellHelper( c );
1026 ASSERT( sIsValid(c) );
1028 //-----------------------------------------------------------------------------
1029 template < DGtal::Dimension dim, typename TInteger>
1032 DGtal::KhalimskySpaceND< dim, TInteger>::
1033 sSetSign( SCell & c, Sign s ) const
1035 PreCellularGridSpace::sSetSign( c.mySPreCell, s );
1037 //-----------------------------------------------------------------------------
1038 // ------------------------- Cell topology services -----------------------
1039 //-----------------------------------------------------------------------------
1040 template < DGtal::Dimension dim, typename TInteger>
1043 DGtal::KhalimskySpaceND< dim, TInteger>::
1044 uTopology( const Cell & p ) const
1046 return PreCellularGridSpace::uTopology( p );
1048 //-----------------------------------------------------------------------------
1049 template < DGtal::Dimension dim, typename TInteger>
1052 DGtal::KhalimskySpaceND< dim, TInteger>::
1053 sTopology( const SCell & p ) const
1055 return PreCellularGridSpace::sTopology( p );
1057 //-----------------------------------------------------------------------------
1058 template < DGtal::Dimension dim, typename TInteger>
1061 DGtal::KhalimskySpaceND< dim, TInteger>::
1062 uDim( const Cell & p ) const
1064 return PreCellularGridSpace::uDim( p );
1066 //-----------------------------------------------------------------------------
1067 template < DGtal::Dimension dim, typename TInteger>
1070 DGtal::KhalimskySpaceND< dim, TInteger>::
1071 sDim( const SCell & p ) const
1073 return PreCellularGridSpace::sDim( p );
1075 //-----------------------------------------------------------------------------
1076 template < DGtal::Dimension dim, typename TInteger>
1079 DGtal::KhalimskySpaceND< dim, TInteger>::
1080 uIsSurfel( const Cell & b ) const
1082 return PreCellularGridSpace::uIsSurfel( b );
1084 //-----------------------------------------------------------------------------
1085 template < DGtal::Dimension dim, typename TInteger>
1088 DGtal::KhalimskySpaceND< dim, TInteger>::
1089 sIsSurfel( const SCell & b ) const
1091 return PreCellularGridSpace::sIsSurfel( b );
1093 //-----------------------------------------------------------------------------
1094 template < DGtal::Dimension dim, typename TInteger>
1097 DGtal::KhalimskySpaceND< dim, TInteger>::
1098 uIsOpen( const Cell & p, DGtal::Dimension k ) const
1100 return PreCellularGridSpace::uIsOpen( p, k );
1102 //-----------------------------------------------------------------------------
1103 template < DGtal::Dimension dim, typename TInteger>
1106 DGtal::KhalimskySpaceND< dim, TInteger>::
1107 sIsOpen( const SCell & p, DGtal::Dimension k ) const
1109 return PreCellularGridSpace::sIsOpen( p, k );
1112 //-----------------------------------------------------------------------------
1113 ///////////////////////////////////////////////////////////////////////////////
1114 //-----------------------------------------------------------------------------
1115 template < DGtal::Dimension dim, typename TInteger>
1117 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1118 DGtal::KhalimskySpaceND< dim, TInteger>::
1119 uDirs( const Cell & p ) const
1121 return PreCellularGridSpace::uDirs( p );
1123 //-----------------------------------------------------------------------------
1124 template < DGtal::Dimension dim, typename TInteger>
1126 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1127 DGtal::KhalimskySpaceND< dim, TInteger>::
1128 sDirs( const SCell & p ) const
1130 return PreCellularGridSpace::sDirs( p );
1132 //-----------------------------------------------------------------------------
1133 template < DGtal::Dimension dim, typename TInteger>
1135 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1136 DGtal::KhalimskySpaceND< dim, TInteger>::
1137 uOrthDirs( const Cell & p ) const
1139 return PreCellularGridSpace::uOrthDirs( p );
1141 //-----------------------------------------------------------------------------
1142 template < DGtal::Dimension dim, typename TInteger>
1144 typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1145 DGtal::KhalimskySpaceND< dim, TInteger>::
1146 sOrthDirs( const SCell & p ) const
1148 return PreCellularGridSpace::sOrthDirs( p );
1150 //-----------------------------------------------------------------------------
1151 template < DGtal::Dimension dim, typename TInteger>
1154 DGtal::KhalimskySpaceND< dim, TInteger>::
1155 uOrthDir( const Cell & s ) const
1157 return PreCellularGridSpace::uOrthDir( s );
1159 //-----------------------------------------------------------------------------
1160 template < DGtal::Dimension dim, typename TInteger>
1163 DGtal::KhalimskySpaceND< dim, TInteger>::
1164 sOrthDir( const SCell & s ) const
1166 return PreCellularGridSpace::sOrthDir( s );
1168 //-----------------------------------------------------------------------------
1169 ///////////////////////////////////////////////////////////////////////////////
1170 //-----------------------------------------------------------------------------
1171 //-----------------------------------------------------------------------------
1172 template < DGtal::Dimension dim, typename TInteger>
1174 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1175 DGtal::KhalimskySpaceND< dim, TInteger>::
1176 uFirst( 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 //-----------------------------------------------------------------------------
1185 template < DGtal::Dimension dim, typename TInteger>
1187 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1188 DGtal::KhalimskySpaceND< dim, TInteger>::
1189 uFirst( const PreCell & p ) const
1192 for ( Dimension k = 0; k < dimension; ++k )
1193 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uFirst( p, k ) );
1197 //-----------------------------------------------------------------------------
1198 template < DGtal::Dimension dim, typename TInteger>
1200 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1201 DGtal::KhalimskySpaceND< dim, TInteger>::
1202 uLast( 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 //-----------------------------------------------------------------------------
1211 template < DGtal::Dimension dim, typename TInteger>
1213 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1214 DGtal::KhalimskySpaceND< dim, TInteger>::
1215 uLast( const PreCell & p ) const
1218 for ( Dimension k = 0; k < dimension; ++k )
1219 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uLast( p, k ) );
1223 //-----------------------------------------------------------------------------
1224 template < DGtal::Dimension dim, typename TInteger>
1226 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1227 DGtal::KhalimskySpaceND< dim, TInteger>::
1228 uGetIncr( const Cell & p, DGtal::Dimension k ) const
1230 Cell cell( PreCellularGridSpace::uGetIncr( p, k ) );
1231 this->updateCellHelper( cell, k );
1232 ASSERT( uIsValid(cell) );
1235 //-----------------------------------------------------------------------------
1236 template < DGtal::Dimension dim, typename TInteger>
1239 DGtal::KhalimskySpaceND< dim, TInteger>::
1240 uIsMax( const Cell & p, DGtal::Dimension k ) const
1243 ASSERT( uIsInside(p) );
1245 ! this->isDimensionPeriodicHelper( k )
1246 && PreCellularGridSpace::uKCoord( p, k ) >= uLast( p, k );
1248 //-----------------------------------------------------------------------------
1249 template < DGtal::Dimension dim, typename TInteger>
1252 DGtal::KhalimskySpaceND< dim, TInteger>::
1253 uIsInside( const PreCell & p, DGtal::Dimension k ) const
1255 return cIsInside( p.coordinates, k );
1257 //-----------------------------------------------------------------------------
1258 template < DGtal::Dimension dim, typename TInteger>
1261 DGtal::KhalimskySpaceND< dim, TInteger>::
1262 uIsInside( const PreCell & p ) const
1264 return cIsInside( p.coordinates );
1266 //-----------------------------------------------------------------------------
1267 template < DGtal::Dimension dim, typename TInteger>
1270 DGtal::KhalimskySpaceND< dim, TInteger>::
1271 cIsInside( const Point & p, DGtal::Dimension k ) const
1274 return this->isDimensionPeriodicHelper( k )
1275 || cIsValid( p, k );
1277 //-----------------------------------------------------------------------------
1278 template < DGtal::Dimension dim, typename TInteger>
1281 DGtal::KhalimskySpaceND< dim, TInteger>::
1282 cIsInside( const Point & p ) const
1284 for ( Dimension k = 0; k < DIM; ++k )
1285 if ( ! cIsInside( p, k ) )
1290 //-----------------------------------------------------------------------------
1291 template < DGtal::Dimension dim, typename TInteger>
1293 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1294 DGtal::KhalimskySpaceND< dim, TInteger>::
1295 uGetMax( Cell p, DGtal::Dimension k ) const
1297 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uLast( p, k ) );
1298 ASSERT( uIsValid( p ) );
1301 //-----------------------------------------------------------------------------
1302 template < DGtal::Dimension dim, typename TInteger>
1304 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1305 DGtal::KhalimskySpaceND< dim, TInteger>::
1306 uGetDecr( const Cell & p, DGtal::Dimension k ) const
1308 Cell cell( PreCellularGridSpace::uGetDecr( p, k ) );
1309 this->updateCellHelper( cell, k );
1310 ASSERT( uIsValid( cell ) );
1313 //-----------------------------------------------------------------------------
1314 template < DGtal::Dimension dim, typename TInteger>
1317 DGtal::KhalimskySpaceND< dim, TInteger>::
1318 uIsMin( const Cell & p, DGtal::Dimension k ) const
1320 ASSERT( uIsInside(p) );
1322 ! this->isDimensionPeriodicHelper( k )
1323 && PreCellularGridSpace::uKCoord( p, k ) <= uFirst( p, k );
1325 //-----------------------------------------------------------------------------
1326 template < DGtal::Dimension dim, typename TInteger>
1328 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1329 DGtal::KhalimskySpaceND< dim, TInteger>::
1330 uGetMin( Cell p, DGtal::Dimension k ) const
1332 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uFirst( p, k ) );
1333 ASSERT( uIsValid(p) );
1336 //-----------------------------------------------------------------------------
1337 template < DGtal::Dimension dim, typename TInteger>
1339 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1340 DGtal::KhalimskySpaceND< dim, TInteger>::
1341 uGetAdd( 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 //-----------------------------------------------------------------------------
1349 template < DGtal::Dimension dim, typename TInteger>
1351 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1352 DGtal::KhalimskySpaceND< dim, TInteger>::
1353 uGetSub( 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 //-----------------------------------------------------------------------------
1361 template < DGtal::Dimension dim, typename TInteger>
1364 DGtal::KhalimskySpaceND< dim, TInteger>::
1365 uDistanceToMax( 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 //-----------------------------------------------------------------------------
1373 template < DGtal::Dimension dim, typename TInteger>
1376 DGtal::KhalimskySpaceND< dim, TInteger>::
1377 uDistanceToMin( 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 //-----------------------------------------------------------------------------
1385 template < DGtal::Dimension dim, typename TInteger>
1387 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1388 DGtal::KhalimskySpaceND< dim, TInteger>::
1389 uTranslation( const Cell & p, const Vector & vec ) const
1391 Cell cell( PreCellularGridSpace::uTranslation( p, vec ) );
1392 this->updateCellHelper( cell );
1393 ASSERT( uIsValid( cell ) );
1396 //-----------------------------------------------------------------------------
1397 template < DGtal::Dimension dim, typename TInteger>
1399 typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1400 DGtal::KhalimskySpaceND< dim, TInteger>::
1401 uProjection( const Cell & p, const Cell & bound, DGtal::Dimension k ) const
1403 Cell cell( PreCellularGridSpace::uProjection( p, bound, k ) );
1404 ASSERT( uIsValid( cell ) );
1407 //-----------------------------------------------------------------------------
1408 template < DGtal::Dimension dim, typename TInteger>
1411 DGtal::KhalimskySpaceND< dim, TInteger>::
1412 uProject( Cell & p, const Cell & bound, DGtal::Dimension k ) const
1414 PreCellularGridSpace::uProject( p.myPreCell, bound, k );
1415 ASSERT( uIsValid( p ) );
1417 //-----------------------------------------------------------------------------
1418 template < DGtal::Dimension dim, typename TInteger>
1421 DGtal::KhalimskySpaceND< dim, TInteger>::
1422 uNext( 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 //-----------------------------------------------------------------------------
1459 template < DGtal::Dimension dim, typename TInteger>
1461 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1462 DGtal::KhalimskySpaceND< dim, TInteger>::
1463 sFirst( 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 //-----------------------------------------------------------------------------
1472 template < DGtal::Dimension dim, typename TInteger>
1474 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1475 DGtal::KhalimskySpaceND< dim, TInteger >::
1476 sFirst( 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 //-----------------------------------------------------------------------------
1487 template < DGtal::Dimension dim, typename TInteger>
1489 typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1490 DGtal::KhalimskySpaceND< dim, TInteger>::
1491 sLast( 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 //-----------------------------------------------------------------------------
1499 template < DGtal::Dimension dim, typename TInteger>
1501 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1502 DGtal::KhalimskySpaceND< dim, TInteger >::
1503 sLast( 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 //-----------------------------------------------------------------------------
1514 template < DGtal::Dimension dim, typename TInteger>
1516 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1517 DGtal::KhalimskySpaceND< dim, TInteger >::
1518 sGetIncr( const SCell & p, DGtal::Dimension k ) const
1520 SCell cell( PreCellularGridSpace::sGetIncr( p, k ) );
1521 this->updateSCellHelper( cell, k );
1522 ASSERT( sIsValid( cell ) );
1525 //-----------------------------------------------------------------------------
1526 template < DGtal::Dimension dim, typename TInteger>
1529 DGtal::KhalimskySpaceND< dim, TInteger >::
1530 sIsMax( const SCell & p, DGtal::Dimension k ) const
1533 ASSERT( sIsInside(p) );
1535 ! this->isDimensionPeriodicHelper( k )
1536 && PreCellularGridSpace::sKCoord( p, k ) >= sLast( p, k );
1538 //-----------------------------------------------------------------------------
1539 template < DGtal::Dimension dim, typename TInteger>
1542 DGtal::KhalimskySpaceND< dim, TInteger>::
1543 sIsInside( const SPreCell & p, DGtal::Dimension k ) const
1545 return cIsInside( p.coordinates, k );
1547 //-----------------------------------------------------------------------------
1548 template < DGtal::Dimension dim, typename TInteger>
1551 DGtal::KhalimskySpaceND< dim, TInteger>::
1552 sIsInside( const SPreCell & p ) const
1554 return cIsInside( p.coordinates );
1556 //-----------------------------------------------------------------------------
1557 template < DGtal::Dimension dim, typename TInteger>
1559 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1560 DGtal::KhalimskySpaceND< dim, TInteger >::
1561 sGetMax( SCell p, DGtal::Dimension k ) const
1563 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sLast( p, k ) );
1564 ASSERT( sIsValid( p ) );
1567 //-----------------------------------------------------------------------------
1568 template < DGtal::Dimension dim, typename TInteger>
1570 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1571 DGtal::KhalimskySpaceND< dim, TInteger >::
1572 sGetDecr( const SCell & p, DGtal::Dimension k ) const
1574 SCell cell( PreCellularGridSpace::sGetDecr( p, k ) );
1575 this->updateSCellHelper( cell, k );
1576 ASSERT( sIsValid( cell ) );
1579 //-----------------------------------------------------------------------------
1580 template < DGtal::Dimension dim, typename TInteger>
1583 DGtal::KhalimskySpaceND< dim, TInteger >::
1584 sIsMin( const SCell & p, DGtal::Dimension k ) const
1587 ASSERT( sIsInside(p) );
1589 ! this->isDimensionPeriodicHelper( k )
1590 && PreCellularGridSpace::sKCoord( p, k ) <= sFirst( p, k );
1592 //-----------------------------------------------------------------------------
1593 template < DGtal::Dimension dim, typename TInteger>
1595 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1596 DGtal::KhalimskySpaceND< dim, TInteger >::
1597 sGetMin( SCell p, DGtal::Dimension k ) const
1599 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sFirst( p, k ) );
1600 ASSERT( sIsValid( p ) );
1603 //-----------------------------------------------------------------------------
1604 template < DGtal::Dimension dim, typename TInteger>
1606 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1607 DGtal::KhalimskySpaceND< dim, TInteger >::
1608 sGetAdd( 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 //-----------------------------------------------------------------------------
1616 template < DGtal::Dimension dim, typename TInteger>
1618 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1619 DGtal::KhalimskySpaceND< dim, TInteger >::
1620 sGetSub( 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 //-----------------------------------------------------------------------------
1628 template < DGtal::Dimension dim, typename TInteger>
1631 DGtal::KhalimskySpaceND< dim, TInteger >::
1632 sDistanceToMax( 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 //-----------------------------------------------------------------------------
1640 template < DGtal::Dimension dim, typename TInteger>
1643 DGtal::KhalimskySpaceND< dim, TInteger >::
1644 sDistanceToMin( 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 //-----------------------------------------------------------------------------
1652 template < DGtal::Dimension dim, typename TInteger>
1654 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1655 DGtal::KhalimskySpaceND< dim, TInteger >::
1656 sTranslation( const SCell & p, const Vector & vec ) const
1658 SCell cell( PreCellularGridSpace::sTranslation( p, vec ) );
1659 this->updateSCellHelper( cell );
1660 ASSERT( sIsValid( cell ) );
1663 //-----------------------------------------------------------------------------
1664 template < DGtal::Dimension dim, typename TInteger>
1666 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1667 DGtal::KhalimskySpaceND< dim, TInteger >::
1668 sProjection( const SCell & p, const SCell & bound, DGtal::Dimension k ) const
1670 SCell cell( PreCellularGridSpace::sProjection( p, bound, k ) );
1671 ASSERT( sIsValid( cell ) );
1674 //-----------------------------------------------------------------------------
1675 template < DGtal::Dimension dim, typename TInteger>
1678 DGtal::KhalimskySpaceND< dim, TInteger >::
1679 sProject( SCell & p, const SCell & bound, DGtal::Dimension k ) const
1681 PreCellularGridSpace::sProject( p.mySPreCell, bound, k );
1682 ASSERT( sIsValid( p ) );
1684 //-----------------------------------------------------------------------------
1685 template < DGtal::Dimension dim, typename TInteger>
1688 DGtal::KhalimskySpaceND< dim, TInteger >::
1689 sNext( 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 //-----------------------------------------------------------------------------
1725 template < DGtal::Dimension dim, typename TInteger>
1727 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1728 DGtal::KhalimskySpaceND< dim, TInteger >::
1729 uNeighborhood( 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 //-----------------------------------------------------------------------------
1745 template < DGtal::Dimension dim, typename TInteger>
1747 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1748 DGtal::KhalimskySpaceND< dim, TInteger >::
1749 sNeighborhood( 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 //-----------------------------------------------------------------------------
1765 template < DGtal::Dimension dim, typename TInteger>
1767 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1768 DGtal::KhalimskySpaceND< dim, TInteger >::
1769 uProperNeighborhood( 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 //-----------------------------------------------------------------------------
1784 template < DGtal::Dimension dim, typename TInteger>
1786 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1787 DGtal::KhalimskySpaceND< dim, TInteger >::
1788 sProperNeighborhood( 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 //-----------------------------------------------------------------------------
1803 template < DGtal::Dimension dim, typename TInteger>
1805 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1806 DGtal::KhalimskySpaceND< dim, TInteger >::
1807 uAdjacent( 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 //-----------------------------------------------------------------------------
1815 template < DGtal::Dimension dim, typename TInteger>
1817 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1818 DGtal::KhalimskySpaceND< dim, TInteger >::
1819 sAdjacent( 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 //-----------------------------------------------------------------------------
1829 template < DGtal::Dimension dim, typename TInteger>
1831 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1832 DGtal::KhalimskySpaceND< dim, TInteger >::
1833 uIncident( 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 //-----------------------------------------------------------------------------
1846 template < DGtal::Dimension dim, typename TInteger>
1848 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1849 DGtal::KhalimskySpaceND< dim, TInteger >::
1850 sIncident( 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 //-----------------------------------------------------------------------------
1863 template < DGtal::Dimension dim, typename TInteger>
1865 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1866 DGtal::KhalimskySpaceND< dim, TInteger >::
1867 uLowerIncident( 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 //-----------------------------------------------------------------------------
1892 template < DGtal::Dimension dim, typename TInteger>
1894 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1895 DGtal::KhalimskySpaceND< dim, TInteger >::
1896 uUpperIncident( 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 //-----------------------------------------------------------------------------
1921 template < DGtal::Dimension dim, typename TInteger>
1923 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1924 DGtal::KhalimskySpaceND< dim, TInteger >::
1925 sLowerIncident( 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 //-----------------------------------------------------------------------------
1950 template < DGtal::Dimension dim, typename TInteger>
1952 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1953 DGtal::KhalimskySpaceND< dim, TInteger >::
1954 sUpperIncident( 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 //-----------------------------------------------------------------------------
1979 template < DGtal::Dimension dim, typename TInteger>
1982 DGtal::KhalimskySpaceND< dim, TInteger >::
1983 uAddFaces( 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 //-----------------------------------------------------------------------------
2011 template < DGtal::Dimension dim, typename TInteger>
2014 DGtal::KhalimskySpaceND< dim, TInteger >::
2015 uAddCoFaces( 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 //-----------------------------------------------------------------------------
2043 template < DGtal::Dimension dim, typename TInteger>
2045 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2046 DGtal::KhalimskySpaceND< dim, TInteger >::
2047 uFaces( const Cell & c ) const
2049 ASSERT( uIsValid(c) );
2052 uAddFaces( N, c, 0 );
2055 //-----------------------------------------------------------------------------
2056 template < DGtal::Dimension dim, typename TInteger>
2058 typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2059 DGtal::KhalimskySpaceND< dim, TInteger >::
2060 uCoFaces( const Cell & c ) const
2062 ASSERT( uIsValid(c) );
2065 uAddCoFaces( N, c, 0 );
2068 //-----------------------------------------------------------------------------
2069 template < DGtal::Dimension dim, typename TInteger>
2072 DGtal::KhalimskySpaceND< dim, TInteger >::
2073 sDirect( const SCell & p, DGtal::Dimension k ) const
2075 return PreCellularGridSpace::sDirect( p, k );
2077 //-----------------------------------------------------------------------------
2078 template < DGtal::Dimension dim, typename TInteger>
2080 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2081 DGtal::KhalimskySpaceND< dim, TInteger >::
2082 sDirectIncident( 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 //-----------------------------------------------------------------------------
2097 template < DGtal::Dimension dim, typename TInteger>
2099 typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2100 DGtal::KhalimskySpaceND< dim, TInteger >::
2101 sIndirectIncident( 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 //-----------------------------------------------------------------------------
2120 template < DGtal::Dimension dim, typename TInteger>
2123 DGtal::KhalimskySpaceND< dim, TInteger>::
2124 selfDisplay ( 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 //-----------------------------------------------------------------------------
2137 template < DGtal::Dimension dim, typename TInteger>
2140 DGtal::KhalimskySpaceND< dim, TInteger>::
2148 ///////////////////////////////////////////////////////////////////////////////
2149 // Implementation of inline functions //
2150 template < DGtal::Dimension dim, typename TInteger>
2153 DGtal::operator<< ( std::ostream & out,
2154 const KhalimskySpaceND< dim, TInteger> & object )
2156 object.selfDisplay( out );
2161 ///////////////////////////////////////////////////////////////////////////////