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 KhalimskyPreSpaceND.ih
19 * @author Roland Denis ( \c roland.denis@univ-smb.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in KhalimskyPreSpaceND.h
26 * This file is part of the DGtal library.
30//////////////////////////////////////////////////////////////////////////////
31#include <DGtal/kernel/NumberTraits.h>
32//////////////////////////////////////////////////////////////////////////////
34///////////////////////////////////////////////////////////////////////////////
35// Namescape scope definition of static constants.
36///////////////////////////////////////////////////////////////////////////////
38template < DGtal::Dimension dim, typename TInteger >
41 DGtal::KhalimskyPreSpaceND<dim, TInteger>::dimension;
43template < DGtal::Dimension dim, typename TInteger >
46 DGtal::KhalimskyPreSpaceND<dim, TInteger>::DIM;
48template < DGtal::Dimension dim, typename TInteger >
50 typename DGtal::KhalimskyPreSpaceND<dim, TInteger>::Sign
51 DGtal::KhalimskyPreSpaceND<dim, TInteger>::POS;
53template < DGtal::Dimension dim, typename TInteger >
55 typename DGtal::KhalimskyPreSpaceND<dim, TInteger>::Sign
56 DGtal::KhalimskyPreSpaceND<dim, TInteger>::NEG;
59///////////////////////////////////////////////////////////////////////////////
60// IMPLEMENTATION of inline methods.
61///////////////////////////////////////////////////////////////////////////////
63///////////////////////////////////////////////////////////////////////////////
65///////////////////////////////////////////////////////////////////////////////
66//-----------------------------------------------------------------------------
67template < DGtal::Dimension dim, typename TInteger >
69DGtal::KhalimskyPreCell< dim, TInteger >::
70KhalimskyPreCell( Integer /* dummy */ )
74//-----------------------------------------------------------------------------
75template < DGtal::Dimension dim, typename TInteger >
77DGtal::KhalimskyPreCell< dim, TInteger >::
78KhalimskyPreCell( Point const& p )
82//-----------------------------------------------------------------------------
83template < DGtal::Dimension dim, typename TInteger >
85DGtal::KhalimskyPreCell< dim, TInteger > const &
86DGtal::KhalimskyPreCell< dim, TInteger >::
91//-----------------------------------------------------------------------------
92template < DGtal::Dimension dim, typename TInteger >
95DGtal::KhalimskyPreCell< dim, TInteger >::
96operator==( const KhalimskyPreCell & other ) const
98 return coordinates == other.coordinates;
100//-----------------------------------------------------------------------------
101template < DGtal::Dimension dim, typename TInteger >
104DGtal::KhalimskyPreCell< dim, TInteger >::
105operator!=( const KhalimskyPreCell & other ) const
107 return coordinates != other.coordinates;
109//-----------------------------------------------------------------------------
110template < DGtal::Dimension dim, typename TInteger >
113DGtal::KhalimskyPreCell< dim, TInteger >::
114operator<( const KhalimskyPreCell & other ) const
116 return coordinates < other.coordinates;
118//-----------------------------------------------------------------------------
119template < DGtal::Dimension dim, typename TInteger >
122DGtal::operator<<( std::ostream & out,
123 const KhalimskyPreCell< dim, TInteger > & object )
125 out << "(" << object.coordinates[ 0 ];
126 for ( DGtal::Dimension i = 1; i < dim; ++i )
127 out << "," << object.coordinates[ i ];
132//------------------------------------------------------------------------------
133template < DGtal::Dimension dim, typename TInteger >
136DGtal::KhalimskyPreCell<dim, TInteger>::
139 return "KhalimskyPreCell";
142///////////////////////////////////////////////////////////////////////////////
143// SignedKhalimskyPreCell
144///////////////////////////////////////////////////////////////////////////////
145//-----------------------------------------------------------------------------
146template < DGtal::Dimension dim, typename TInteger >
148DGtal::SignedKhalimskyPreCell< dim, TInteger >::
149SignedKhalimskyPreCell( Integer /* dummy */ )
154//-----------------------------------------------------------------------------
155template < DGtal::Dimension dim, typename TInteger >
157DGtal::SignedKhalimskyPreCell< dim, TInteger >::
158SignedKhalimskyPreCell( Point const& p, bool aPositive )
160 , positive( aPositive )
163//-----------------------------------------------------------------------------
164template < DGtal::Dimension dim, typename TInteger >
166DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
167DGtal::SignedKhalimskyPreCell< dim, TInteger >::
172//-----------------------------------------------------------------------------
173template < DGtal::Dimension dim, typename TInteger >
176DGtal::SignedKhalimskyPreCell< dim, TInteger >::
177operator==( const SignedKhalimskyPreCell & other ) const
179 return ( positive == other.positive )
180 && ( coordinates == other.coordinates );
182//-----------------------------------------------------------------------------
183template < DGtal::Dimension dim, typename TInteger >
186DGtal::SignedKhalimskyPreCell< dim, TInteger >::
187operator!=( const SignedKhalimskyPreCell & other ) const
189 return ( positive != other.positive )
190 || ( coordinates != other.coordinates );
192//-----------------------------------------------------------------------------
193template < DGtal::Dimension dim, typename TInteger >
196DGtal::SignedKhalimskyPreCell< dim, TInteger >::
197operator<( const SignedKhalimskyPreCell & other ) const
199 return ( positive < other.positive )
200 || ( ( positive == other.positive )
201 && ( coordinates < other.coordinates ) );
203//-----------------------------------------------------------------------------
204template < DGtal::Dimension dim,
208DGtal::operator<<( std::ostream & out,
209 const SignedKhalimskyPreCell< dim, TInteger > & object )
211 out << "(" << object.coordinates[ 0 ];
212 for ( DGtal::Dimension i = 1; i < dim; ++i )
213 out << "," << object.coordinates[ i ];
214 out << "," << ( object.positive ? '+' : '-' );
219//------------------------------------------------------------------------------
220template < DGtal::Dimension dim, typename TInteger >
223DGtal::SignedKhalimskyPreCell<dim, TInteger>::
226 return "SignedKhalimskyPreCell";
229///////////////////////////////////////////////////////////////////////////////
230// PreCellDirectionIterator
231///////////////////////////////////////////////////////////////////////////////
232//-----------------------------------------------------------------------------
233template < DGtal::Dimension dim, typename TInteger >
235DGtal::PreCellDirectionIterator< dim, TInteger >::
236PreCellDirectionIterator( Cell cell, bool open )
237 : myDir( 0 ), myCell( cell ), myOpen( open )
241//-----------------------------------------------------------------------------
242template < DGtal::Dimension dim, typename TInteger >
244DGtal::PreCellDirectionIterator< dim, TInteger >::
245PreCellDirectionIterator( SCell scell, bool open )
246 : myDir( 0 ), myCell( scell.coordinates ), myOpen( open )
250//-----------------------------------------------------------------------------
251template < DGtal::Dimension dim, typename TInteger >
254DGtal::PreCellDirectionIterator< dim, TInteger >::
259//-----------------------------------------------------------------------------
260template < DGtal::Dimension dim, typename TInteger >
262DGtal::PreCellDirectionIterator< dim, TInteger > &
263DGtal::PreCellDirectionIterator< dim, TInteger >::
270//-----------------------------------------------------------------------------
271template < DGtal::Dimension dim, typename TInteger >
274DGtal::PreCellDirectionIterator< dim, TInteger >::
275operator!=( const Integer ) const
279//-----------------------------------------------------------------------------
280template < DGtal::Dimension dim, typename TInteger >
283DGtal::PreCellDirectionIterator< dim, TInteger >::
288//-----------------------------------------------------------------------------
289template < DGtal::Dimension dim, typename TInteger >
292DGtal::PreCellDirectionIterator< dim, TInteger >::
293operator!=( const PreCellDirectionIterator & other ) const
295 return myDir != other.myDir;
297//-----------------------------------------------------------------------------
298template < DGtal::Dimension dim, typename TInteger >
301DGtal::PreCellDirectionIterator< dim, TInteger >::
302operator==( const PreCellDirectionIterator & other ) const
304 return myDir == other.myDir;
306//-----------------------------------------------------------------------------
307template < DGtal::Dimension dim, typename TInteger >
310DGtal::PreCellDirectionIterator< dim, TInteger >::
313 if ( myOpen ) // loop on open coordinates
314 while ( myDir != dim && NumberTraits<Integer>::even( myCell.coordinates[ myDir ] ) )
316 else // myOpen is false, loop on closed coordinates
317 while ( myDir != dim && NumberTraits<Integer>::odd( myCell.coordinates[ myDir ] ) )
321///////////////////////////////////////////////////////////////////////////////
322// KhalimskyPreSpaceND
323///////////////////////////////////////////////////////////////////////////////
324///////////////////////////////////////////////////////////////////////////////
325template < DGtal::Dimension dim, typename TInteger>
327typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
328DGtal::KhalimskyPreSpaceND< dim, TInteger>::
329uCell( const Point & kp )
333//-----------------------------------------------------------------------------
334template < DGtal::Dimension dim, typename TInteger>
336typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
337DGtal::KhalimskyPreSpaceND< dim, TInteger>::
338uCell( Point p, const Cell & c )
340 for ( DGtal::Dimension i = 0; i < dimension; ++i )
342 p[ i ] += p[ i ] + ( NumberTraits<Integer>::odd( c.coordinates[ i ] ) ? 1 : 0 );
346//-----------------------------------------------------------------------------
347template < DGtal::Dimension dim, typename TInteger>
349typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
350DGtal::KhalimskyPreSpaceND< dim, TInteger>::
351sCell( const Point & kp, Sign sign )
353 return SCell( kp, sign == POS );
355//-----------------------------------------------------------------------------
356template < DGtal::Dimension dim, typename TInteger>
358typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
359DGtal::KhalimskyPreSpaceND< dim, TInteger>::
360sCell( Point p, const SCell & c )
362 for ( DGtal::Dimension i = 0; i < DIM; ++i )
363 p[ i ] += p[ i ] + ( NumberTraits<Integer>::odd( c.coordinates[ i ] ) ? 1 : 0 );
364 return sCell( p, c.positive );
366//-----------------------------------------------------------------------------
367template < DGtal::Dimension dim, typename TInteger>
369typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
370DGtal::KhalimskyPreSpaceND< dim, TInteger>::
373 for ( DGtal::Dimension i = 0; i < DIM; ++i )
374 p[ i ] += p[ i ] + 1;
377//-----------------------------------------------------------------------------
378template < DGtal::Dimension dim, typename TInteger>
380typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
381DGtal::KhalimskyPreSpaceND< dim, TInteger>::
382sSpel( Point p, Sign sign )
384 for ( DGtal::Dimension i = 0; i < DIM; ++i )
385 p[ i ] += p[ i ] + 1;
386 return sCell( p, sign );
388//-----------------------------------------------------------------------------
389template < DGtal::Dimension dim, typename TInteger>
391typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
392DGtal::KhalimskyPreSpaceND< dim, TInteger>::
395 for ( DGtal::Dimension i = 0; i < DIM; ++i )
399//-----------------------------------------------------------------------------
400template < DGtal::Dimension dim, typename TInteger>
402typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
403DGtal::KhalimskyPreSpaceND< dim, TInteger>::
404sPointel( Point p, Sign sign )
406 for ( DGtal::Dimension i = 0; i < DIM; ++i )
408 return sCell( p, sign );
410//-----------------------------------------------------------------------------
411///////////////////////////////////////////////////////////////////////////////
412//-----------------------------------------------------------------------------
413template < DGtal::Dimension dim, typename TInteger>
415typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
416DGtal::KhalimskyPreSpaceND< dim, TInteger>::
417uKCoord( const Cell & c, DGtal::Dimension k )
420 return c.coordinates[ k ];
422//-----------------------------------------------------------------------------
423template < DGtal::Dimension dim, typename TInteger>
425typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
426DGtal::KhalimskyPreSpaceND< dim, TInteger>::
427uCoord( const Cell & c, DGtal::Dimension k )
430 return c.coordinates[ k ] >> 1;
432//-----------------------------------------------------------------------------
433template < DGtal::Dimension dim, typename TInteger>
435typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point const &
436DGtal::KhalimskyPreSpaceND< dim, TInteger>::
437uKCoords( const Cell & c )
439 return c.coordinates;
441//-----------------------------------------------------------------------------
442template < DGtal::Dimension dim, typename TInteger>
444typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point
445DGtal::KhalimskyPreSpaceND< dim, TInteger>::
446uCoords( const Cell & c )
448 Point dp = uKCoords( c );
449 for ( DGtal::Dimension i = 0; i < DIM; ++i )
453//-----------------------------------------------------------------------------
454template < DGtal::Dimension dim, typename TInteger>
456typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
457DGtal::KhalimskyPreSpaceND< dim, TInteger>::
458sKCoord( const SCell & c, DGtal::Dimension k )
461 return c.coordinates[ k ];
463//-----------------------------------------------------------------------------
464template < DGtal::Dimension dim, typename TInteger>
466typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
467DGtal::KhalimskyPreSpaceND< dim, TInteger>::
468sCoord( const SCell & c, DGtal::Dimension k )
471 return c.coordinates[ k ] >> 1;
473//-----------------------------------------------------------------------------
474template < DGtal::Dimension dim, typename TInteger>
476typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point const &
477DGtal::KhalimskyPreSpaceND< dim, TInteger>::
478sKCoords( const SCell & c )
480 return c.coordinates;
482//-----------------------------------------------------------------------------
483template < DGtal::Dimension dim, typename TInteger>
485typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point
486DGtal::KhalimskyPreSpaceND< dim, TInteger>::
487sCoords( const SCell & c )
489 Point dp = sKCoords( c );
490 for ( DGtal::Dimension i = 0; i < DIM; ++i )
494//-----------------------------------------------------------------------------
495template < DGtal::Dimension dim, typename TInteger>
497typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Sign
498DGtal::KhalimskyPreSpaceND< dim, TInteger>::
499sSign( const SCell & c )
501 return c.positive ? POS : NEG;
503//-----------------------------------------------------------------------------
504template < DGtal::Dimension dim, typename TInteger>
506typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
507DGtal::KhalimskyPreSpaceND< dim, TInteger>::
508signs( const Cell & p, Sign s )
510 return sCell( p.coordinates, s );
512//-----------------------------------------------------------------------------
513template < DGtal::Dimension dim, typename TInteger>
515typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
516DGtal::KhalimskyPreSpaceND< dim, TInteger>::
517unsigns( const SCell & p )
519 return uCell( p.coordinates );
521//-----------------------------------------------------------------------------
522template < DGtal::Dimension dim, typename TInteger>
524typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
525DGtal::KhalimskyPreSpaceND< dim, TInteger>::
526sOpp( const SCell & p )
528 return sCell( p.coordinates, ! p.positive );
530//-----------------------------------------------------------------------------
531template < DGtal::Dimension dim, typename TInteger>
534DGtal::KhalimskyPreSpaceND< dim, TInteger>::
535uSetKCoord( Cell & c, DGtal::Dimension k, Integer i )
538 c.coordinates[ k ] = i;
540//-----------------------------------------------------------------------------
541template < DGtal::Dimension dim, typename TInteger>
544DGtal::KhalimskyPreSpaceND< dim, TInteger>::
545sSetKCoord( SCell & c, DGtal::Dimension k, Integer i )
548 c.coordinates[ k ] = i;
550//-----------------------------------------------------------------------------
551template < DGtal::Dimension dim, typename TInteger>
554DGtal::KhalimskyPreSpaceND< dim, TInteger>::
555uSetCoord( Cell & c, DGtal::Dimension k, Integer i )
558 c.coordinates[ k ] = 2 * i + ( NumberTraits<Integer>::odd( c.coordinates[ k ] ) ? 1 : 0 );
560//-----------------------------------------------------------------------------
561template < DGtal::Dimension dim, typename TInteger>
564DGtal::KhalimskyPreSpaceND< dim, TInteger>::
565sSetCoord( SCell & c, DGtal::Dimension k, Integer i )
568 c.coordinates[ k ] = 2 * i + ( NumberTraits<Integer>::odd( c.coordinates[ k ] ) ? 1 : 0 );
570//-----------------------------------------------------------------------------
571template < DGtal::Dimension dim, typename TInteger>
574DGtal::KhalimskyPreSpaceND< dim, TInteger>::
575uSetKCoords( Cell & c, const Point & kp )
579//-----------------------------------------------------------------------------
580template < DGtal::Dimension dim, typename TInteger>
583DGtal::KhalimskyPreSpaceND< dim, TInteger>::
584sSetKCoords( SCell & c, const Point & kp )
588//-----------------------------------------------------------------------------
589template < DGtal::Dimension dim, typename TInteger>
592DGtal::KhalimskyPreSpaceND< dim, TInteger>::
593uSetCoords( Cell & c, const Point & p )
595 for ( DGtal::Dimension k = 0; k < DIM; ++k )
596 uSetCoord( c, k, p[k] );
598//-----------------------------------------------------------------------------
599template < DGtal::Dimension dim, typename TInteger>
602DGtal::KhalimskyPreSpaceND< dim, TInteger>::
603sSetCoords( SCell & c, const Point & p )
605 for ( DGtal::Dimension k = 0; k < DIM; ++k )
606 sSetCoord( c, k, p[k] );
608//-----------------------------------------------------------------------------
609template < DGtal::Dimension dim, typename TInteger>
612DGtal::KhalimskyPreSpaceND< dim, TInteger>::
613sSetSign( SCell & c, Sign s )
615 c.positive = ( s == POS );
617//-----------------------------------------------------------------------------
618// ------------------------- Cell topology services -----------------------
619//-----------------------------------------------------------------------------
620template < DGtal::Dimension dim, typename TInteger>
623DGtal::KhalimskyPreSpaceND< dim, TInteger>::
624uTopology( const Cell & p )
626 Integer i = NumberTraits<Integer>::ZERO;
627 Integer j = NumberTraits<Integer>::ONE;
628 for ( DGtal::Dimension k = 0; k < DIM; ++k )
630 if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
636//-----------------------------------------------------------------------------
637template < DGtal::Dimension dim, typename TInteger>
640DGtal::KhalimskyPreSpaceND< dim, TInteger>::
641sTopology( const SCell & p )
643 Integer i = NumberTraits<Integer>::ZERO;
644 Integer j = NumberTraits<Integer>::ONE;
645 for ( DGtal::Dimension k = 0; k < DIM; ++k )
647 if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
653//-----------------------------------------------------------------------------
654template < DGtal::Dimension dim, typename TInteger>
657DGtal::KhalimskyPreSpaceND< dim, TInteger>::
658uDim( const Cell & p )
660 DGtal::Dimension i = NumberTraits<DGtal::Dimension>::ZERO;
661 for ( DGtal::Dimension k = 0; k < DIM; ++k )
662 if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
666//-----------------------------------------------------------------------------
667template < DGtal::Dimension dim, typename TInteger>
670DGtal::KhalimskyPreSpaceND< dim, TInteger>::
671sDim( const SCell & p )
673 DGtal::Dimension i = NumberTraits<DGtal::Dimension>::ZERO;
674 for ( DGtal::Dimension k = 0; k < DIM; ++k )
675 if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
679//-----------------------------------------------------------------------------
680template < DGtal::Dimension dim, typename TInteger>
683DGtal::KhalimskyPreSpaceND< dim, TInteger>::
684uIsSurfel( const Cell & b )
686 return uDim( b ) == ( DIM - 1 );
688//-----------------------------------------------------------------------------
689template < DGtal::Dimension dim, typename TInteger>
692DGtal::KhalimskyPreSpaceND< dim, TInteger>::
693sIsSurfel( const SCell & b )
695 return sDim( b ) == ( DIM - 1 );
697//-----------------------------------------------------------------------------
698template < DGtal::Dimension dim, typename TInteger>
701DGtal::KhalimskyPreSpaceND< dim, TInteger>::
702uIsOpen( const Cell & p, DGtal::Dimension k )
704 return NumberTraits<Integer>::odd( p.coordinates[ k ] );
706//-----------------------------------------------------------------------------
707template < DGtal::Dimension dim, typename TInteger>
710DGtal::KhalimskyPreSpaceND< dim, TInteger>::
711sIsOpen( const SCell & p, DGtal::Dimension k )
713 return NumberTraits<Integer>::odd( p.coordinates[ k ] );
716//-----------------------------------------------------------------------------
717///////////////////////////////////////////////////////////////////////////////
718//-----------------------------------------------------------------------------
719template < DGtal::Dimension dim, typename TInteger>
721typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
722DGtal::KhalimskyPreSpaceND< dim, TInteger>::
723uDirs( const Cell & p )
725 return DirIterator( p, true );
727//-----------------------------------------------------------------------------
728template < DGtal::Dimension dim, typename TInteger>
730typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
731DGtal::KhalimskyPreSpaceND< dim, TInteger>::
732sDirs( const SCell & p )
734 return DirIterator( p, true );
736//-----------------------------------------------------------------------------
737template < DGtal::Dimension dim, typename TInteger>
739typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
740DGtal::KhalimskyPreSpaceND< dim, TInteger>::
741uOrthDirs( const Cell & p )
743 return DirIterator( p, false );
745//-----------------------------------------------------------------------------
746template < DGtal::Dimension dim, typename TInteger>
748typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
749DGtal::KhalimskyPreSpaceND< dim, TInteger>::
750sOrthDirs( const SCell & p )
752 return DirIterator( p, false );
754//-----------------------------------------------------------------------------
755template < DGtal::Dimension dim, typename TInteger>
758DGtal::KhalimskyPreSpaceND< dim, TInteger>::
759uOrthDir( const Cell & s )
761 DirIterator it( s, false );
762 ASSERT( ! it.end() );
765//-----------------------------------------------------------------------------
766template < DGtal::Dimension dim, typename TInteger>
769DGtal::KhalimskyPreSpaceND< dim, TInteger>::
770sOrthDir( const SCell & s )
772 DirIterator it( s, false );
773 ASSERT( ! it.end() );
776//-----------------------------------------------------------------------------
777///////////////////////////////////////////////////////////////////////////////
778//-----------------------------------------------------------------------------
779template < DGtal::Dimension dim, typename TInteger>
781typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
782DGtal::KhalimskyPreSpaceND< dim, TInteger>::
783uGetIncr( Cell p, DGtal::Dimension k )
786 p.coordinates[ k ] += 2;
789//-----------------------------------------------------------------------------
790template < DGtal::Dimension dim, typename TInteger>
793DGtal::KhalimskyPreSpaceND< dim, TInteger>::
794uIsMax( const Cell &, DGtal::Dimension )
798//-----------------------------------------------------------------------------
799template < DGtal::Dimension dim, typename TInteger>
802DGtal::KhalimskyPreSpaceND< dim, TInteger>::
803uIsMin( const Cell &, DGtal::Dimension )
807//-----------------------------------------------------------------------------
808template < DGtal::Dimension dim, typename TInteger>
811DGtal::KhalimskyPreSpaceND< dim, TInteger>::
812uIsInside( const Cell &, DGtal::Dimension )
816//-----------------------------------------------------------------------------
817template < DGtal::Dimension dim, typename TInteger>
820DGtal::KhalimskyPreSpaceND< dim, TInteger>::
821uIsInside( const Cell & )
825//-----------------------------------------------------------------------------
826template < DGtal::Dimension dim, typename TInteger>
828typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
829DGtal::KhalimskyPreSpaceND< dim, TInteger>::
830uGetDecr( Cell p, DGtal::Dimension k )
832 p.coordinates[ k ] -= 2;
835//-----------------------------------------------------------------------------
836template < DGtal::Dimension dim, typename TInteger>
838typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
839DGtal::KhalimskyPreSpaceND< dim, TInteger>::
840uGetAdd( Cell p, DGtal::Dimension k, Integer x )
842 p.coordinates[ k ] += 2 * x;
845//-----------------------------------------------------------------------------
846template < DGtal::Dimension dim, typename TInteger>
848typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
849DGtal::KhalimskyPreSpaceND< dim, TInteger>::
850uGetSub( Cell p, DGtal::Dimension k, Integer x )
853 p.coordinates[ k ] -= 2 * x;
856//-----------------------------------------------------------------------------
857template < DGtal::Dimension dim, typename TInteger>
859typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
860DGtal::KhalimskyPreSpaceND< dim, TInteger>::
861uTranslation( Cell p, const Vector & vec )
863 for ( DGtal::Dimension k = 0; k < DIM; ++k )
864 p.coordinates[ k ] += 2 * vec[ k ];
868//-----------------------------------------------------------------------------
869template < DGtal::Dimension dim, typename TInteger>
871typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
872DGtal::KhalimskyPreSpaceND< dim, TInteger>::
873uProjection( Cell p, const Cell & bound, DGtal::Dimension k )
876 ASSERT( uIsOpen(p, k) == uIsOpen(bound, k) );
877 p.coordinates[ k ] = bound.coordinates[ k ];
880//-----------------------------------------------------------------------------
881template < DGtal::Dimension dim, typename TInteger>
884DGtal::KhalimskyPreSpaceND< dim, TInteger>::
885uProject( Cell & p, const Cell & bound, DGtal::Dimension k )
888 ASSERT( uIsOpen(p, k) == uIsOpen(bound, k) );
889 p.coordinates[ k ] = bound.coordinates[ k ];
891//-----------------------------------------------------------------------------
892template < DGtal::Dimension dim, typename TInteger>
895DGtal::KhalimskyPreSpaceND< dim, TInteger>::
896uNext( Cell & p, const Cell & lower, const Cell & upper )
898 ASSERT( uTopology(p) == uTopology(lower)
899 && uTopology(p) == uTopology(upper) );
901 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
902 if ( uKCoord( p, k ) == uKCoord( upper, k ) )
904 if ( p == upper ) return false;
905 uProject( p, lower, k );
906 for ( k = 1; k < DIM; ++k )
908 if ( uKCoord( p, k ) == uKCoord( upper, k ) )
909 uProject( p, lower, k );
912 p.coordinates[ k ] += 2;
919 p.coordinates[ k ] += 2;
923//-----------------------------------------------------------------------------
924///////////////////////////////////////////////////////////////////////////////
925//-----------------------------------------------------------------------------
926template < DGtal::Dimension dim, typename TInteger>
928typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
929DGtal::KhalimskyPreSpaceND< dim, TInteger >::
930sGetIncr( SCell p, DGtal::Dimension k )
933 p.coordinates[ k ] += 2;;
936//-----------------------------------------------------------------------------
937template < DGtal::Dimension dim, typename TInteger>
940DGtal::KhalimskyPreSpaceND< dim, TInteger>::
941sIsMax( const SCell &, DGtal::Dimension )
945//-----------------------------------------------------------------------------
946template < DGtal::Dimension dim, typename TInteger>
949DGtal::KhalimskyPreSpaceND< dim, TInteger>::
950sIsMin( const SCell &, DGtal::Dimension )
954//-----------------------------------------------------------------------------
955template < DGtal::Dimension dim, typename TInteger>
958DGtal::KhalimskyPreSpaceND< dim, TInteger>::
959sIsInside( const SCell &, DGtal::Dimension )
963//-----------------------------------------------------------------------------
964template < DGtal::Dimension dim, typename TInteger>
967DGtal::KhalimskyPreSpaceND< dim, TInteger>::
968sIsInside( const SCell & )
972//-----------------------------------------------------------------------------
973template < DGtal::Dimension dim, typename TInteger>
975typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
976DGtal::KhalimskyPreSpaceND< dim, TInteger >::
977sGetDecr( SCell p, DGtal::Dimension k )
980 p.coordinates[ k ] -= 2;;
983//-----------------------------------------------------------------------------
984template < DGtal::Dimension dim, typename TInteger>
986typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
987DGtal::KhalimskyPreSpaceND< dim, TInteger >::
988sGetAdd( SCell p, DGtal::Dimension k, Integer x )
991 p.coordinates[ k ] += 2 * x;;
994//-----------------------------------------------------------------------------
995template < DGtal::Dimension dim, typename TInteger>
997typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
998DGtal::KhalimskyPreSpaceND< dim, TInteger >::
999sGetSub( SCell p, DGtal::Dimension k, Integer x )
1002 p.coordinates[ k ] -= 2 * x;;
1005//-----------------------------------------------------------------------------
1006template < DGtal::Dimension dim, typename TInteger>
1008typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1009DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1010sTranslation( SCell p, const Vector & vec )
1012 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1013 p.coordinates[ k ] += 2 * vec[ k ];
1017//-----------------------------------------------------------------------------
1018template < DGtal::Dimension dim, typename TInteger>
1020typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1021DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1022sProjection( SCell p, const SCell & bound, DGtal::Dimension k )
1025 ASSERT( sIsOpen(p, k) == sIsOpen(bound, k) );
1026 p.coordinates[ k ] = bound.coordinates[ k ];
1029//-----------------------------------------------------------------------------
1030template < DGtal::Dimension dim, typename TInteger>
1033DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1034sProject( SCell & p, const SCell & bound, DGtal::Dimension k )
1037 ASSERT( sIsOpen(p, k) == sIsOpen(bound, k) );
1038 p.coordinates[ k ] = bound.coordinates[ k ];
1040//-----------------------------------------------------------------------------
1041template < DGtal::Dimension dim, typename TInteger>
1044DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1045sNext( SCell & p, const SCell & lower, const SCell & upper )
1047 ASSERT( sTopology(p) == sTopology(lower)
1048 && sTopology(p) == sTopology(upper) );
1050 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1051 if ( sCoord( p, k ) == sCoord( upper, k ) )
1053 if ( p == upper ) return false;
1054 sProject( p, lower, k );
1055 for ( k = 1; k < DIM; ++k )
1057 if ( sCoord( p, k ) == sCoord( upper, k ) )
1058 sProject( p, lower, k );
1061 p.coordinates[ k ] += 2;;
1068 p.coordinates[ k ] += 2;
1072//-----------------------------------------------------------------------------
1073// ----------------------- Neighborhood services --------------------------
1074//-----------------------------------------------------------------------------
1075template < DGtal::Dimension dim, typename TInteger>
1077typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1078DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1079uNeighborhood( const Cell & c )
1083 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1085 N.push_back( uGetDecr( c, k ) );
1086 N.push_back( uGetIncr( c, k ) );
1090//-----------------------------------------------------------------------------
1091template < DGtal::Dimension dim, typename TInteger>
1093typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1094DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1095sNeighborhood( const SCell & c )
1099 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1101 N.push_back( sGetDecr( c, k ) );
1102 N.push_back( sGetIncr( c, k ) );
1106//-----------------------------------------------------------------------------
1107template < DGtal::Dimension dim, typename TInteger>
1109typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1110DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1111uProperNeighborhood( const Cell & c )
1114 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1116 N.push_back( uGetDecr( c, k ) );
1117 N.push_back( uGetIncr( c, k ) );
1121//-----------------------------------------------------------------------------
1122template < DGtal::Dimension dim, typename TInteger>
1124typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1125DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1126sProperNeighborhood( const SCell & c )
1129 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1131 N.push_back( sGetDecr( c, k ) );
1132 N.push_back( sGetIncr( c, k ) );
1136//-----------------------------------------------------------------------------
1137template < DGtal::Dimension dim, typename TInteger>
1139typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cell
1140DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1141uAdjacent( const Cell & p, DGtal::Dimension k, bool up )
1144 return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1146//-----------------------------------------------------------------------------
1147template < DGtal::Dimension dim, typename TInteger>
1149typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1150DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1151sAdjacent( const SCell & p, DGtal::Dimension k, bool up )
1154 return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1157// ----------------------- Incidence services --------------------------
1158//-----------------------------------------------------------------------------
1159template < DGtal::Dimension dim, typename TInteger>
1161typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cell
1162DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1163uIncident( Cell c, DGtal::Dimension k, bool up )
1167 if ( up ) ++c.coordinates[ k ];
1168 else --c.coordinates[ k ];
1172//-----------------------------------------------------------------------------
1173template < DGtal::Dimension dim, typename TInteger>
1175typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1176DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1177sIncident( SCell c, DGtal::Dimension k, bool up )
1181 bool sign = up ? c.positive : ! c.positive;
1182 for ( DGtal::Dimension i = 0; i <= k; ++i )
1183 if ( sIsOpen( c, i ) )
1187 if ( up ) ++c.coordinates[ k ];
1188 else --c.coordinates[ k ];
1192//-----------------------------------------------------------------------------
1193template < DGtal::Dimension dim, typename TInteger>
1195typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1196DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1197uLowerIncident( const Cell & c )
1200 for ( auto q = uDirs( c ); q != 0; ++q )
1202 const DGtal::Dimension k = *q;
1203 N.push_back( uIncident( c, k, false ) );
1204 N.push_back( uIncident( c, k, true ) );
1208//-----------------------------------------------------------------------------
1209template < DGtal::Dimension dim, typename TInteger>
1211typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1212DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1213uUpperIncident( const Cell & c )
1216 for ( auto q = uOrthDirs( c ); q != 0; ++q )
1218 const DGtal::Dimension k = *q;
1219 N.push_back( uIncident( c, k, false ) );
1220 N.push_back( uIncident( c, k, true ) );
1224//-----------------------------------------------------------------------------
1225template < DGtal::Dimension dim, typename TInteger>
1227typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1228DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1229sLowerIncident( const SCell & c )
1232 for ( auto q = sDirs( c ); q != 0; ++q )
1234 const DGtal::Dimension k = *q;
1235 N.push_back( sIncident( c, k, false ) );
1236 N.push_back( sIncident( c, k, true ) );
1240//-----------------------------------------------------------------------------
1241template < DGtal::Dimension dim, typename TInteger>
1243typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1244DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1245sUpperIncident( const SCell & c )
1248 for ( auto q = sOrthDirs( c ); q != 0; ++q )
1250 const DGtal::Dimension k = *q;
1251 N.push_back( sIncident( c, k, false ) );
1252 N.push_back( sIncident( c, k, true ) );
1256//-----------------------------------------------------------------------------
1257template < DGtal::Dimension dim, typename TInteger>
1260DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1261uAddFaces( Cells& faces, const Cell& c, Dimension axis )
1263 const DGtal::Dimension dim_of_c = uDim( c );
1264 if ( axis >= dim_of_c ) return;
1266 DirIterator q = uDirs( c );
1267 for ( Dimension i = 0; i < axis; ++i ) ++q;
1269 Cell f1 = uIncident( c, *q, false );
1270 Cell f2 = uIncident( c, *q, true );
1272 faces.push_back( f1 );
1273 faces.push_back( f2 );
1275 uAddFaces( faces, f1, axis );
1276 uAddFaces( faces, f2, axis );
1278 uAddFaces( faces, c, axis+1 );
1280//-----------------------------------------------------------------------------
1281template < DGtal::Dimension dim, typename TInteger>
1284DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1285uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis )
1287 const DGtal::Dimension dim_of_c = uDim( c );
1288 if ( axis >= dimension - dim_of_c ) return;
1290 DirIterator q = uOrthDirs( c );
1291 for ( Dimension i = 0; i < axis; ++i ) ++q;
1293 Cell f1 = uIncident( c, *q, false );
1294 Cell f2 = uIncident( c, *q, true );
1296 cofaces.push_back( f1 );
1297 cofaces.push_back( f2 );
1299 uAddCoFaces( cofaces, f1, axis );
1300 uAddCoFaces( cofaces, f2, axis );
1302 uAddCoFaces( cofaces, c, axis+1 );
1304//-----------------------------------------------------------------------------
1305template < DGtal::Dimension dim, typename TInteger>
1307typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1308DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1309uFaces( const Cell & c )
1312 uAddFaces( N, c, 0 );
1315//-----------------------------------------------------------------------------
1316template < DGtal::Dimension dim, typename TInteger>
1318typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1319DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1320uCoFaces( const Cell & c )
1323 uAddCoFaces( N, c, 0 );
1326//-----------------------------------------------------------------------------
1327template < DGtal::Dimension dim, typename TInteger>
1330DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1331sDirect( const SCell & p, DGtal::Dimension k )
1335 bool sign = p.positive;
1336 for ( DGtal::Dimension i = 0; i <= k; ++i )
1337 if ( sIsOpen( p, i ) )
1341//-----------------------------------------------------------------------------
1342template < DGtal::Dimension dim, typename TInteger>
1344typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1345DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1346sDirectIncident( SCell p, DGtal::Dimension k )
1350 bool sign = p.positive;
1351 for ( DGtal::Dimension i = 0; i <= k; ++i )
1352 if ( sIsOpen( p, i ) )
1358 if ( up ) ++p.coordinates[ k ];
1359 else --p.coordinates[ k ];
1363//-----------------------------------------------------------------------------
1364template < DGtal::Dimension dim, typename TInteger>
1366typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1367DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1368sIndirectIncident( SCell p, DGtal::Dimension k )
1372 bool sign = p.positive;
1373 for ( DGtal::Dimension i = 0; i <= k; ++i )
1374 if ( sIsOpen( p, i ) )
1380 if ( up ) ++p.coordinates[ k ];
1381 else --p.coordinates[ k ];
1385//-----------------------------------------------------------------------------
1386template < DGtal::Dimension dim, typename TInteger>
1388typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Point
1389DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1390interiorVoxel( const SCell &p)
1392 ASSERT(sDim(p) == (dimension - 1));
1393 auto d = sOrthDir( p );
1394 auto voxel = sIncident( p, d, sDirect( p, d ) );
1395 return sCoords( voxel );
1397//-----------------------------------------------------------------------------
1398template < DGtal::Dimension dim, typename TInteger>
1400typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Point
1401DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1402exteriorVoxel( const SCell &p)
1404 ASSERT(sDim(p) == (dimension - 1));
1405 auto d = sOrthDir( p );
1406 auto voxel = sIncident( p, d, !sDirect( p, d ) );
1407 return sCoords( voxel );
1412//-----------------------------------------------------------------------------
1413template < DGtal::Dimension dim, typename TInteger>
1416DGtal::KhalimskyPreSpaceND< dim, TInteger>::
1417selfDisplay ( std::ostream & out )
1419 out << "[KhalimskyPreSpaceND<" << dimension << ">]";
1421//-----------------------------------------------------------------------------
1422template < DGtal::Dimension dim, typename TInteger>
1425DGtal::KhalimskyPreSpaceND< dim, TInteger>::
1433///////////////////////////////////////////////////////////////////////////////
1434// Implementation of inline functions //
1435template < DGtal::Dimension dim, typename TInteger>
1438DGtal::operator<< ( std::ostream & out,
1439 const KhalimskyPreSpaceND< dim, TInteger> & object )
1441 object.selfDisplay( out );
1446///////////////////////////////////////////////////////////////////////////////