DGtal 1.4.0
Loading...
Searching...
No Matches
KhalimskySpaceND.ih
1/**
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.
6 *
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.
11 *
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/>.
14 *
15 **/
16
17/**
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
21 *
22 * @date 2011/02/08
23 *
24 * Implementation of inline methods defined in KhalimskySpaceND.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <DGtal/io/Color.h>
32#include <DGtal/kernel/NumberTraits.h>
33//////////////////////////////////////////////////////////////////////////////
34
35///////////////////////////////////////////////////////////////////////////////
36// Namescape scope definition of static constants.
37///////////////////////////////////////////////////////////////////////////////
38
39template < DGtal::Dimension dim, typename TInteger >
40 const constexpr
41 DGtal::Dimension
42 DGtal::KhalimskySpaceND<dim, TInteger>::dimension;
43
44template < DGtal::Dimension dim, typename TInteger >
45 const constexpr
46 DGtal::Dimension
47 DGtal::KhalimskySpaceND<dim, TInteger>::DIM;
48
49template < DGtal::Dimension dim, typename TInteger >
50 const constexpr
51 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
52 DGtal::KhalimskySpaceND<dim, TInteger>::POS;
53
54template < DGtal::Dimension dim, typename TInteger >
55 const constexpr
56 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
57 DGtal::KhalimskySpaceND<dim, TInteger>::NEG;
58
59///////////////////////////////////////////////////////////////////////////////
60// IMPLEMENTATION of inline methods.
61///////////////////////////////////////////////////////////////////////////////
62
63///////////////////////////////////////////////////////////////////////////////
64// KhalimskyCell
65///////////////////////////////////////////////////////////////////////////////
66//-----------------------------------------------------------------------------
67template < DGtal::Dimension dim, typename TInteger >
68inline
69DGtal::KhalimskyCell< dim, TInteger >::
70KhalimskyCell( Integer )
71 : myPreCell()
72{
73}
74//-----------------------------------------------------------------------------
75template < DGtal::Dimension dim, typename TInteger >
76inline
77DGtal::KhalimskyCell< dim, TInteger >::
78KhalimskyCell( const Point & p )
79 : myPreCell( p )
80{
81}
82//-----------------------------------------------------------------------------
83template < DGtal::Dimension dim, typename TInteger >
84inline
85DGtal::KhalimskyCell< dim, TInteger >::
86KhalimskyCell( const PreCell & aCell )
87 : myPreCell( aCell )
88{
89}
90//-----------------------------------------------------------------------------
91template < DGtal::Dimension dim, typename TInteger >
92inline
93DGtal::KhalimskyCell< dim, TInteger >::
94operator DGtal::KhalimskyPreCell< dim, TInteger > const& () const
95{
96 return myPreCell;
97}
98//-----------------------------------------------------------------------------
99template < DGtal::Dimension dim, typename TInteger >
100inline
101DGtal::KhalimskyPreCell< dim, TInteger > const &
102DGtal::KhalimskyCell< dim, TInteger >::
103preCell () const
104{
105 return myPreCell;
106}
107//-----------------------------------------------------------------------------
108template < DGtal::Dimension dim, typename TInteger >
109inline
110DGtal::KhalimskyCell< dim, TInteger >::
111operator DGtal::KhalimskyPreCell< dim, TInteger > & ()
112{
113 return myPreCell;
114}
115//-----------------------------------------------------------------------------
116template < DGtal::Dimension dim, typename TInteger >
117inline
118bool
119DGtal::KhalimskyCell< dim, TInteger >::
120operator==( const KhalimskyCell & other ) const
121{
122 return myPreCell == other.myPreCell;
123}
124//-----------------------------------------------------------------------------
125template < DGtal::Dimension dim, typename TInteger >
126inline
127bool
128DGtal::KhalimskyCell< dim, TInteger >::
129operator!=( const KhalimskyCell & other ) const
130{
131 return myPreCell != other.myPreCell;
132}
133//-----------------------------------------------------------------------------
134template < DGtal::Dimension dim, typename TInteger >
135inline
136bool
137DGtal::KhalimskyCell< dim, TInteger >::
138operator<( const KhalimskyCell & other ) const
139{
140 return myPreCell < other.myPreCell;
141}
142//-----------------------------------------------------------------------------
143template < DGtal::Dimension dim, typename TInteger >
144inline
145std::ostream &
146DGtal::operator<<( std::ostream & out,
147 const KhalimskyCell< dim, TInteger > & object )
148{
149 out << static_cast< const KhalimskyPreCell<dim, TInteger> & >(object);
150 return out;
151}
152
153//------------------------------------------------------------------------------
154template < DGtal::Dimension dim, typename TInteger >
155inline
156std::string
157DGtal::KhalimskyCell<dim, TInteger>::
158className() const
159{
160 return "KhalimskyCell";
161}
162
163///////////////////////////////////////////////////////////////////////////////
164// SignedKhalimskyCell
165///////////////////////////////////////////////////////////////////////////////
166//-----------------------------------------------------------------------------
167template < DGtal::Dimension dim, typename TInteger >
168inline
169DGtal::SignedKhalimskyCell< dim, TInteger >::
170SignedKhalimskyCell( Integer )
171 : mySPreCell()
172{
173}
174//-----------------------------------------------------------------------------
175template < DGtal::Dimension dim, typename TInteger >
176inline
177DGtal::SignedKhalimskyCell< dim, TInteger >::
178SignedKhalimskyCell( const Point & p, bool positive )
179 : mySPreCell( p, positive )
180{
181}
182//-----------------------------------------------------------------------------
183template < DGtal::Dimension dim, typename TInteger >
184inline
185DGtal::SignedKhalimskyCell< dim, TInteger >::
186SignedKhalimskyCell( const SPreCell & aCell )
187 : mySPreCell( aCell )
188{
189}
190//-----------------------------------------------------------------------------
191template < DGtal::Dimension dim, typename TInteger >
192inline
193DGtal::SignedKhalimskyCell< dim, TInteger >::
194operator DGtal::SignedKhalimskyPreCell< dim, TInteger > const& () const
195{
196 return mySPreCell;
197}
198//-----------------------------------------------------------------------------
199template < DGtal::Dimension dim, typename TInteger >
200inline
201DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
202DGtal::SignedKhalimskyCell< dim, TInteger >::
203preCell() const
204{
205 return mySPreCell;
206}
207//-----------------------------------------------------------------------------
208template < DGtal::Dimension dim, typename TInteger >
209inline
210DGtal::SignedKhalimskyCell< dim, TInteger >::
211operator DGtal::SignedKhalimskyPreCell< dim, TInteger > & ()
212{
213 return mySPreCell;
214}
215//-----------------------------------------------------------------------------
216template < DGtal::Dimension dim, typename TInteger >
217inline
218bool
219DGtal::SignedKhalimskyCell< dim, TInteger >::
220operator==( const SignedKhalimskyCell & other ) const
221{
222 return mySPreCell == other.mySPreCell;
223}
224//-----------------------------------------------------------------------------
225template < DGtal::Dimension dim, typename TInteger >
226inline
227bool
228DGtal::SignedKhalimskyCell< dim, TInteger >::
229operator!=( const SignedKhalimskyCell & other ) const
230{
231 return mySPreCell != other.mySPreCell;
232}
233//-----------------------------------------------------------------------------
234template < DGtal::Dimension dim, typename TInteger >
235inline
236bool
237DGtal::SignedKhalimskyCell< dim, TInteger >::
238operator<( const SignedKhalimskyCell & other ) const
239{
240 return mySPreCell < other.mySPreCell;
241}
242//-----------------------------------------------------------------------------
243template < DGtal::Dimension dim,
244 typename TInteger >
245inline
246std::ostream &
247DGtal::operator<<( std::ostream & out,
248 const SignedKhalimskyCell< dim, TInteger > & object )
249{
250 out << static_cast< const SignedKhalimskyPreCell<dim, TInteger> & >(object);
251 return out;
252}
253
254//------------------------------------------------------------------------------
255template < DGtal::Dimension dim, typename TInteger >
256inline
257std::string
258DGtal::SignedKhalimskyCell<dim, TInteger>::
259className() const
260{
261 return "SignedKhalimskyCell";
262}
263
264///////////////////////////////////////////////////////////////////////////////
265// KhalimskySpaceNDHelper
266///////////////////////////////////////////////////////////////////////////////
267namespace DGtal
268{
269
270template <
271 DGtal::Dimension dim,
272 typename TInteger
273>
274class KhalimskySpaceNDHelper< KhalimskySpaceND< dim, TInteger > >
275{
276private:
277 // Private typedefs
278 using KhalimskySpace = KhalimskySpaceND< dim, TInteger >;
279 using Point = PointVector< dim, TInteger >;
280 using Cell = KhalimskyCell< dim, TInteger >;
281 using SCell = SignedKhalimskyCell< dim, TInteger >;
282
283 /// Returns derived mutable instance
284 KhalimskySpace& derived()
285 {
286 return *static_cast<KhalimskySpace*>(this);
287 }
288
289 /// Returns derived constant instance
290 KhalimskySpace const & derived() const
291 {
292 return *static_cast<KhalimskySpace const*>(this);
293 }
294
295
296public:
297 // Provided helpers
298
299 /// @return true is the specified dimension is periodic
300 inline
301 bool isDimensionPeriodicHelper( DGtal::Dimension d ) const
302 {
303 return derived().myClosure[ d ] == KhalimskySpace::PERIODIC;
304 }
305
306 /// @return true is there is at least one periodic dimension.
307 inline
308 bool isAnyDimensionPeriodicHelper() const
309 {
310 return myIsAnyDimensionPeriodic;
311 }
312
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.
316 */
317 inline
318 void updateKCoordHelper( typename Point::Coordinate & aKCoord, DGtal::Dimension d ) const
319 {
320 if ( isDimensionPeriodicHelper( d ) )
321 {
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 ]
326 );
327 }
328 }
329
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.
334 */
335 inline
336 typename Point::Coordinate returnKCoordHelper( typename Point::Coordinate aKCoord, DGtal::Dimension d ) const
337 {
338 updateKCoordHelper( aKCoord, d );
339 return aKCoord;
340 }
341
342 /** Modifies khalimsky coordinates of a point according to the dimension periodicity.
343 * @param[in,out] aKCoords the khalimksy coordinates.
344 */
345 inline
346 void updateKCoordsHelper( Point & aKCoords ) const
347 {
348 if ( isAnyDimensionPeriodicHelper() )
349 {
350 for ( DGtal::Dimension i = 0; i < dim; ++i )
351 updateKCoordHelper( aKCoords[ i ], i );
352 }
353 }
354
355 /** Returns given khalimsky coordinates of a point modified according to the dimension periodicity.
356 * @param[in] aKCoords the khalimksy coordinates.
357 */
358 inline
359 Point returnKCoordsHelper( Point aKCoords ) const
360 {
361 updateKCoordsHelper( aKCoords );
362 return aKCoords;
363 }
364
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.
368 */
369 inline
370 void updateCellHelper( Cell & aCell, DGtal::Dimension d ) const
371 {
372 updateKCoordHelper( aCell.myPreCell.coordinates[ d ], d );
373 }
374
375 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
376 * @param[in,out] aCell an unsigned cell.
377 */
378 inline
379 void updateCellHelper( Cell & aCell ) const
380 {
381 updateKCoordsHelper( aCell.myPreCell.coordinates );
382 }
383
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.
387 */
388 inline
389 void updateSCellHelper( SCell & aCell, DGtal::Dimension d ) const
390 {
391 updateKCoordHelper( aCell.mySPreCell.coordinates[ d ], d );
392 }
393
394 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
395 * @param[in,out] aCell a signed cell.
396 */
397 inline
398 void updateSCellHelper( SCell & aCell ) const
399 {
400 updateKCoordsHelper( aCell.mySPreCell.coordinates );
401 }
402
403public:
404 /// Initialization
405 bool initHelper()
406 {
407 myIsAnyDimensionPeriodic = false;
408 for ( DGtal::Dimension i = 0; i < dim; ++i )
409 {
410 myIsAnyDimensionPeriodic |= isDimensionPeriodicHelper( i );
411 myCellExtent[ i ] = derived().myCellUpper.myPreCell.coordinates[ i ] - derived().myCellLower.myPreCell.coordinates[ i ] + 1;
412 }
413
414 return true;
415 }
416
417
418private:
419 // Optimization data
420 Point myCellExtent; ///< Extent between the extremal cells.
421 bool myIsAnyDimensionPeriodic; ///< true if there is at least one periodic dimension.
422};
423
424} // namespace DGtal
425
426///////////////////////////////////////////////////////////////////////////////
427// KhalimskySpaceND
428///////////////////////////////////////////////////////////////////////////////
429///////////////////////////////////////////////////////////////////////////////
430// ----------------------- Standard services ------------------------------
431//-----------------------------------------------------------------------------
432template < DGtal::Dimension dim, typename TInteger>
433inline
434DGtal::KhalimskySpaceND< dim, TInteger>::
435~KhalimskySpaceND()
436{
437}
438//-----------------------------------------------------------------------------
439template < DGtal::Dimension dim, typename TInteger>
440inline
441DGtal::KhalimskySpaceND< dim, TInteger>::
442KhalimskySpaceND()
443{
444 Point low, high;
445 for ( DGtal::Dimension i = 0; i < dimension; ++i )
446 {
447 low[ i ] = NumberTraits< Integer >::min() / 2 + 1;
448 high[ i ] = NumberTraits< Integer >::max() / 2 - 1;
449 }
450 init( low, high, true );
451}
452//-----------------------------------------------------------------------------
453template < DGtal::Dimension dim, typename TInteger>
454inline
455DGtal::KhalimskySpaceND< dim, TInteger>::
456KhalimskySpaceND( const Point & lower,
457 const Point & upper,
458 bool isClosed)
459{
460 init( lower, upper, isClosed );
461}
462//-----------------------------------------------------------------------------
463template < DGtal::Dimension dim, typename TInteger>
464inline
465bool
466DGtal::KhalimskySpaceND< dim, TInteger>::
467init( const Point & lower,
468 const Point & upper,
469 bool isClosed )
470{
471 std::array<Closure, dimension> closure;
472 for ( DGtal::Dimension i = 0; i < dimension; ++i )
473 closure[ i ] = isClosed ? CLOSED : OPEN;
474
475 return init( lower, upper, closure );
476}
477//-----------------------------------------------------------------------------
478template < DGtal::Dimension dim, typename TInteger>
479inline
480bool
481DGtal::KhalimskySpaceND< dim, TInteger>::
482init( const Point & lower,
483 const Point & upper,
484 Closure closure )
485{
486 std::array<Closure, dimension> dimClosure;
487 dimClosure.fill( closure );
488
489 return init( lower, upper, dimClosure );
490}
491
492//-----------------------------------------------------------------------------
493template < DGtal::Dimension dim, typename TInteger>
494inline
495bool
496DGtal::KhalimskySpaceND< dim, TInteger>::
497init( const Point & lower,
498 const Point & upper,
499 const std::array<Closure, dim> & closure )
500{
501 myLower = lower;
502 myUpper = upper;
503 myClosure = closure;
504
505 if ( NumberTraits< Integer >::isBounded() == BOUNDED )
506 {
507 for ( DGtal::Dimension i = 0; i < dimension; ++i )
508 {
509 if ( ( lower[ i ] <= ( NumberTraits< Integer >::min() / 2 ) )
510 || ( upper[ i ] >= ( NumberTraits< Integer >::max() / 2 ) ) )
511 return false;
512 }
513 }
514
515 for ( DGtal::Dimension i = 0; i < dimension; ++i )
516 {
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 ) );
519
520 }
521
522 return this->initHelper();
523}
524//-----------------------------------------------------------------------------
525template < DGtal::Dimension dim, typename TInteger>
526inline
527typename DGtal::KhalimskySpaceND< dim, TInteger>::Size
528DGtal::KhalimskySpaceND< dim, TInteger>::
529size( DGtal::Dimension k ) const
530{
531 ASSERT( k < dimension );
532 return myUpper[ k ] + NumberTraits<Integer>::ONE - myLower[ k ];
533}
534//-----------------------------------------------------------------------------
535template < DGtal::Dimension dim, typename TInteger>
536inline
537TInteger
538DGtal::KhalimskySpaceND< dim, TInteger>::
539min( DGtal::Dimension k ) const
540{
541 return myLower[ k ];
542}
543//-----------------------------------------------------------------------------
544template < DGtal::Dimension dim, typename TInteger>
545inline
546TInteger
547DGtal::KhalimskySpaceND< dim, TInteger>::
548max( DGtal::Dimension k ) const
549{
550 return myUpper[ k ];
551}
552//-----------------------------------------------------------------------------
553template < DGtal::Dimension dim, typename TInteger>
554inline
555const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
556DGtal::KhalimskySpaceND< dim, TInteger>::
557lowerBound() const
558{
559 return myLower;
560}
561//-----------------------------------------------------------------------------
562template < DGtal::Dimension dim, typename TInteger>
563inline
564const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
565DGtal::KhalimskySpaceND< dim, TInteger>::
566upperBound() const
567{
568 return myUpper;
569}
570//-----------------------------------------------------------------------------
571template < DGtal::Dimension dim, typename TInteger>
572inline
573const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
574DGtal::KhalimskySpaceND< dim, TInteger>::
575lowerCell() const
576{
577 return myCellLower;
578}
579//-----------------------------------------------------------------------------
580template < DGtal::Dimension dim, typename TInteger>
581inline
582const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
583DGtal::KhalimskySpaceND< dim, TInteger>::
584upperCell() const
585{
586 return myCellUpper;
587}
588//-----------------------------------------------------------------------------
589template < DGtal::Dimension dim, typename TInteger>
590inline
591bool
592DGtal::KhalimskySpaceND< dim, TInteger>::
593uIsValid( const PreCell & p, Dimension k ) const
594{
595 return cIsValid( p.coordinates, k );
596}
597//-----------------------------------------------------------------------------
598template < DGtal::Dimension dim, typename TInteger>
599inline
600bool
601DGtal::KhalimskySpaceND< dim, TInteger>::
602uIsValid( const PreCell & p ) const
603{
604 return cIsValid( p.coordinates );
605}
606//-----------------------------------------------------------------------------
607template < DGtal::Dimension dim, typename TInteger>
608inline
609bool
610DGtal::KhalimskySpaceND< dim, TInteger>::
611cIsValid( const Point & p, Dimension k ) const
612{
613 return p[ k ] <= PreCellularGridSpace::uKCoord( myCellUpper, k )
614 && p[ k ] >= PreCellularGridSpace::uKCoord( myCellLower, k );
615}
616//-----------------------------------------------------------------------------
617template < DGtal::Dimension dim, typename TInteger>
618inline
619bool
620DGtal::KhalimskySpaceND< dim, TInteger>::
621cIsValid( const Point & p ) const
622{
623 for ( Dimension k = 0; k < DIM; ++ k )
624 if ( ! cIsValid( p, k ) )
625 return false;
626
627 return true;
628}
629//-----------------------------------------------------------------------------
630template < DGtal::Dimension dim, typename TInteger>
631inline
632bool
633DGtal::KhalimskySpaceND< dim, TInteger>::
634sIsValid( const SPreCell & p, Dimension k ) const
635{
636 return cIsValid( p.coordinates, k );
637}
638//-----------------------------------------------------------------------------
639template < DGtal::Dimension dim, typename TInteger>
640inline
641bool
642DGtal::KhalimskySpaceND< dim, TInteger>::
643sIsValid( const SPreCell & p ) const
644{
645 return cIsValid( p.coordinates );
646}
647//-----------------------------------------------------------------------------
648template < DGtal::Dimension dim, typename TInteger>
649inline
650bool
651DGtal::KhalimskySpaceND< dim, TInteger>::
652isSpaceClosed() const
653{
654 for ( Dimension i = 0; i < dimension; ++i )
655 if ( myClosure[ i ] == OPEN )
656 return false;
657
658 return true;
659}
660//-----------------------------------------------------------------------------
661template < DGtal::Dimension dim, typename TInteger>
662inline
663bool
664DGtal::KhalimskySpaceND< dim, TInteger>::
665isSpaceClosed( Dimension k ) const
666{
667 return myClosure[ k ] != OPEN;
668}
669//-----------------------------------------------------------------------------
670template < DGtal::Dimension dim, typename TInteger>
671inline
672bool
673DGtal::KhalimskySpaceND< dim, TInteger>::
674isSpacePeriodic() const
675{
676 for ( Dimension i = 0; i < dimension; ++i )
677 if ( myClosure[ i ] != PERIODIC )
678 return false;
679
680 return true;
681}
682//-----------------------------------------------------------------------------
683template < DGtal::Dimension dim, typename TInteger>
684inline
685bool
686DGtal::KhalimskySpaceND< dim, TInteger>::
687isSpacePeriodic( Dimension k ) const
688{
689 return myClosure[ k ] == PERIODIC;
690}
691//-----------------------------------------------------------------------------
692template < DGtal::Dimension dim, typename TInteger>
693inline
694bool
695DGtal::KhalimskySpaceND< dim, TInteger>::
696isAnyDimensionPeriodic() const
697{
698 return this->isAnyDimensionPeriodicHelper();
699}
700//-----------------------------------------------------------------------------
701template < DGtal::Dimension dim, typename TInteger>
702inline
703typename DGtal::KhalimskySpaceND< dim, TInteger>::Closure
704DGtal::KhalimskySpaceND< dim, TInteger>::
705getClosure(Dimension k) const
706{
707 return myClosure[k];
708}
709//-----------------------------------------------------------------------------
710template < DGtal::Dimension dim, typename TInteger>
711inline
712typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
713DGtal::KhalimskySpaceND< dim, TInteger>::
714uCell( const PreCell & c ) const
715{
716 return uCell( c.coordinates );
717}
718//-----------------------------------------------------------------------------
719template < DGtal::Dimension dim, typename TInteger>
720inline
721typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
722DGtal::KhalimskySpaceND< dim, TInteger>::
723uCell( const Point & kp ) const
724{
725 ASSERT( cIsInside( kp ) );
726 return Cell( this->returnKCoordsHelper( kp ) );
727}
728//-----------------------------------------------------------------------------
729template < DGtal::Dimension dim, typename TInteger>
730inline
731typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
732DGtal::KhalimskySpaceND< dim, TInteger>::
733uCell( Point p, const PreCell & c ) const
734{
735 return uCell( PreCellularGridSpace::uCell( p, c ) );
736}
737//-----------------------------------------------------------------------------
738template < DGtal::Dimension dim, typename TInteger>
739inline
740typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
741DGtal::KhalimskySpaceND< dim, TInteger>::
742sCell( const SPreCell & c ) const
743{
744 return sCell( c.coordinates, c.positive ? POS : NEG );
745}
746//-----------------------------------------------------------------------------
747template < DGtal::Dimension dim, typename TInteger>
748inline
749typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
750DGtal::KhalimskySpaceND< dim, TInteger>::
751sCell( const Point & kp, Sign sign ) const
752{
753 ASSERT( cIsInside( kp ) );
754 return SCell( this->returnKCoordsHelper( kp ), sign == POS );
755}
756//-----------------------------------------------------------------------------
757template < DGtal::Dimension dim, typename TInteger>
758inline
759typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
760DGtal::KhalimskySpaceND< dim, TInteger>::
761sCell( Point p, const SPreCell & c ) const
762{
763 return sCell( PreCellularGridSpace::sCell( p, c ) );
764}
765//-----------------------------------------------------------------------------
766template < DGtal::Dimension dim, typename TInteger>
767inline
768typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
769DGtal::KhalimskySpaceND< dim, TInteger>::
770uSpel( Point p ) const
771{
772 return uCell( PreCellularGridSpace::uSpel( p ) );
773}
774//-----------------------------------------------------------------------------
775template < DGtal::Dimension dim, typename TInteger>
776inline
777typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
778DGtal::KhalimskySpaceND< dim, TInteger>::
779sSpel( Point p, Sign sign ) const
780{
781 return sCell( PreCellularGridSpace::sSpel( p, sign ) );
782}
783//-----------------------------------------------------------------------------
784template < DGtal::Dimension dim, typename TInteger>
785inline
786typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
787DGtal::KhalimskySpaceND< dim, TInteger>::
788uPointel( Point p ) const
789{
790 return uCell( PreCellularGridSpace::uPointel( p ) );
791}
792//-----------------------------------------------------------------------------
793template < DGtal::Dimension dim, typename TInteger>
794inline
795typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
796DGtal::KhalimskySpaceND< dim, TInteger>::
797sPointel( Point p, Sign sign ) const
798{
799 return sCell( PreCellularGridSpace::sPointel( p, sign ) );
800}
801//-----------------------------------------------------------------------------
802///////////////////////////////////////////////////////////////////////////////
803//-----------------------------------------------------------------------------
804template < DGtal::Dimension dim, typename TInteger>
805inline
806typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
807DGtal::KhalimskySpaceND< dim, TInteger>::
808uKCoord( const Cell & c, DGtal::Dimension k ) const
809{
810 ASSERT( uIsValid(c) );
811 return PreCellularGridSpace::uKCoord( c, k );
812}
813//-----------------------------------------------------------------------------
814template < DGtal::Dimension dim, typename TInteger>
815inline
816typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
817DGtal::KhalimskySpaceND< dim, TInteger>::
818uCoord( const Cell & c, DGtal::Dimension k ) const
819{
820 ASSERT( uIsValid(c) );
821 return PreCellularGridSpace::uCoord( c, k );
822}
823//-----------------------------------------------------------------------------
824template < DGtal::Dimension dim, typename TInteger>
825inline
826typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
827DGtal::KhalimskySpaceND< dim, TInteger>::
828uKCoords( const Cell & c ) const
829{
830 ASSERT( uIsValid(c) );
831 return PreCellularGridSpace::uKCoords( c );
832}
833//-----------------------------------------------------------------------------
834template < DGtal::Dimension dim, typename TInteger>
835inline
836typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
837DGtal::KhalimskySpaceND< dim, TInteger>::
838uCoords( const Cell & c ) const
839{
840 ASSERT( uIsValid(c) );
841 return PreCellularGridSpace::uCoords( c );
842}
843//-----------------------------------------------------------------------------
844template < DGtal::Dimension dim, typename TInteger>
845inline
846typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
847DGtal::KhalimskySpaceND< dim, TInteger>::
848interiorVoxel( const SCell & sc ) const
849{
850 ASSERT( sIsValid(sc) );
851 return PreCellularGridSpace::interiorVoxel( sc );
852}
853//-----------------------------------------------------------------------------
854template < DGtal::Dimension dim, typename TInteger>
855inline
856typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
857DGtal::KhalimskySpaceND< dim, TInteger>::
858exteriorVoxel( const SCell & sc ) const
859{
860 ASSERT( sIsValid(sc) );
861 return PreCellularGridSpace::exteriorVoxel( sc );
862}
863//-----------------------------------------------------------------------------
864template < DGtal::Dimension dim, typename TInteger>
865inline
866typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
867DGtal::KhalimskySpaceND< dim, TInteger>::
868sKCoord( const SCell & c, DGtal::Dimension k ) const
869{
870 ASSERT( sIsValid(c) );
871 return PreCellularGridSpace::sKCoord( c, k );
872}
873//-----------------------------------------------------------------------------
874template < DGtal::Dimension dim, typename TInteger>
875inline
876typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
877DGtal::KhalimskySpaceND< dim, TInteger>::
878sCoord( const SCell & c, DGtal::Dimension k ) const
879{
880 ASSERT( sIsValid(c) );
881 return PreCellularGridSpace::sCoord( c, k );
882}
883//-----------------------------------------------------------------------------
884template < DGtal::Dimension dim, typename TInteger>
885inline
886typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
887DGtal::KhalimskySpaceND< dim, TInteger>::
888sKCoords( const SCell & c ) const
889{
890 ASSERT( sIsValid(c) );
891 return PreCellularGridSpace::sKCoords( c );
892}
893//-----------------------------------------------------------------------------
894template < DGtal::Dimension dim, typename TInteger>
895inline
896typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
897DGtal::KhalimskySpaceND< dim, TInteger>::
898sCoords( const SCell & c ) const
899{
900 ASSERT( sIsValid(c) );
901 return PreCellularGridSpace::sCoords( c );
902}
903//-----------------------------------------------------------------------------
904template < DGtal::Dimension dim, typename TInteger>
905inline
906typename DGtal::KhalimskySpaceND< dim, TInteger>::Sign
907DGtal::KhalimskySpaceND< dim, TInteger>::
908sSign( const SCell & c ) const
909{
910 ASSERT( sIsValid(c) );
911 return PreCellularGridSpace::sSign( c );
912}
913//-----------------------------------------------------------------------------
914template < DGtal::Dimension dim, typename TInteger>
915inline
916typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
917DGtal::KhalimskySpaceND< dim, TInteger>::
918signs( const Cell & p, Sign s ) const
919{
920 return sCell( PreCellularGridSpace::signs( p, s ) );
921}
922//-----------------------------------------------------------------------------
923template < DGtal::Dimension dim, typename TInteger>
924inline
925typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
926DGtal::KhalimskySpaceND< dim, TInteger>::
927unsigns( const SCell & p ) const
928{
929 return uCell( PreCellularGridSpace::unsigns( p ) );
930}
931//-----------------------------------------------------------------------------
932template < DGtal::Dimension dim, typename TInteger>
933inline
934typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
935DGtal::KhalimskySpaceND< dim, TInteger>::
936sOpp( const SCell & p ) const
937{
938 return sCell( PreCellularGridSpace::sOpp( p ) );
939}
940//-----------------------------------------------------------------------------
941template < DGtal::Dimension dim, typename TInteger>
942inline
943void
944DGtal::KhalimskySpaceND< dim, TInteger>::
945uSetKCoord( Cell & c, DGtal::Dimension k, Integer i ) const
946{
947 PreCellularGridSpace::uSetKCoord( c.myPreCell, k, i );
948 this->updateCellHelper( c, k );
949 ASSERT( uIsValid(c) );
950}
951//-----------------------------------------------------------------------------
952template < DGtal::Dimension dim, typename TInteger>
953inline
954void
955DGtal::KhalimskySpaceND< dim, TInteger>::
956sSetKCoord( SCell & c, DGtal::Dimension k, Integer i ) const
957{
958 PreCellularGridSpace::sSetKCoord( c.mySPreCell, k, i );
959 this->updateSCellHelper( c, k );
960 ASSERT( sIsValid(c) );
961}
962//-----------------------------------------------------------------------------
963template < DGtal::Dimension dim, typename TInteger>
964inline
965void
966DGtal::KhalimskySpaceND< dim, TInteger>::
967uSetCoord( Cell & c, DGtal::Dimension k, Integer i ) const
968{
969 PreCellularGridSpace::uSetCoord( c.myPreCell, k, i );
970 this->updateCellHelper( c, k );
971 ASSERT( uIsValid(c) );
972}
973//-----------------------------------------------------------------------------
974template < DGtal::Dimension dim, typename TInteger>
975inline
976void
977DGtal::KhalimskySpaceND< dim, TInteger>::
978sSetCoord( SCell & c, DGtal::Dimension k, Integer i ) const
979{
980 PreCellularGridSpace::sSetCoord( c.mySPreCell, k, i );
981 this->updateSCellHelper( c, k );
982 ASSERT( sIsValid(c) );
983}
984//-----------------------------------------------------------------------------
985template < DGtal::Dimension dim, typename TInteger>
986inline
987void
988DGtal::KhalimskySpaceND< dim, TInteger>::
989uSetKCoords( Cell & c, const Point & kp ) const
990{
991 PreCellularGridSpace::uSetKCoords( c.myPreCell, kp );
992 this->updateCellHelper( c );
993 ASSERT( uIsValid(c) );
994}
995//-----------------------------------------------------------------------------
996template < DGtal::Dimension dim, typename TInteger>
997inline
998void
999DGtal::KhalimskySpaceND< dim, TInteger>::
1000sSetKCoords( SCell & c, const Point & kp ) const
1001{
1002 PreCellularGridSpace::sSetKCoords( c.mySPreCell, kp );
1003 this->updateSCellHelper( c );
1004 ASSERT( sIsValid(c) );
1005}
1006//-----------------------------------------------------------------------------
1007template < DGtal::Dimension dim, typename TInteger>
1008inline
1009void
1010DGtal::KhalimskySpaceND< dim, TInteger>::
1011uSetCoords( Cell & c, const Point & p ) const
1012{
1013 PreCellularGridSpace::uSetCoords( c.myPreCell, p );
1014 this->updateCellHelper( c );
1015 ASSERT( uIsValid(c) );
1016}
1017//-----------------------------------------------------------------------------
1018template < DGtal::Dimension dim, typename TInteger>
1019inline
1020void
1021DGtal::KhalimskySpaceND< dim, TInteger>::
1022sSetCoords( SCell & c, const Point & p ) const
1023{
1024 PreCellularGridSpace::sSetCoords( c.mySPreCell, p );
1025 this->updateSCellHelper( c );
1026 ASSERT( sIsValid(c) );
1027}
1028//-----------------------------------------------------------------------------
1029template < DGtal::Dimension dim, typename TInteger>
1030inline
1031void
1032DGtal::KhalimskySpaceND< dim, TInteger>::
1033sSetSign( SCell & c, Sign s ) const
1034{
1035 PreCellularGridSpace::sSetSign( c.mySPreCell, s );
1036}
1037//-----------------------------------------------------------------------------
1038// ------------------------- Cell topology services -----------------------
1039//-----------------------------------------------------------------------------
1040template < DGtal::Dimension dim, typename TInteger>
1041inline
1042TInteger
1043DGtal::KhalimskySpaceND< dim, TInteger>::
1044uTopology( const Cell & p ) const
1045{
1046 return PreCellularGridSpace::uTopology( p );
1047}
1048//-----------------------------------------------------------------------------
1049template < DGtal::Dimension dim, typename TInteger>
1050inline
1051TInteger
1052DGtal::KhalimskySpaceND< dim, TInteger>::
1053sTopology( const SCell & p ) const
1054{
1055 return PreCellularGridSpace::sTopology( p );
1056}
1057//-----------------------------------------------------------------------------
1058template < DGtal::Dimension dim, typename TInteger>
1059inline
1060DGtal::Dimension
1061DGtal::KhalimskySpaceND< dim, TInteger>::
1062uDim( const Cell & p ) const
1063{
1064 return PreCellularGridSpace::uDim( p );
1065}
1066//-----------------------------------------------------------------------------
1067template < DGtal::Dimension dim, typename TInteger>
1068inline
1069DGtal::Dimension
1070DGtal::KhalimskySpaceND< dim, TInteger>::
1071sDim( const SCell & p ) const
1072{
1073 return PreCellularGridSpace::sDim( p );
1074}
1075//-----------------------------------------------------------------------------
1076template < DGtal::Dimension dim, typename TInteger>
1077inline
1078bool
1079DGtal::KhalimskySpaceND< dim, TInteger>::
1080uIsSurfel( const Cell & b ) const
1081{
1082 return PreCellularGridSpace::uIsSurfel( b );
1083}
1084//-----------------------------------------------------------------------------
1085template < DGtal::Dimension dim, typename TInteger>
1086inline
1087bool
1088DGtal::KhalimskySpaceND< dim, TInteger>::
1089sIsSurfel( const SCell & b ) const
1090{
1091 return PreCellularGridSpace::sIsSurfel( b );
1092}
1093//-----------------------------------------------------------------------------
1094template < DGtal::Dimension dim, typename TInteger>
1095inline
1096bool
1097DGtal::KhalimskySpaceND< dim, TInteger>::
1098uIsOpen( const Cell & p, DGtal::Dimension k ) const
1099{
1100 return PreCellularGridSpace::uIsOpen( p, k );
1101}
1102//-----------------------------------------------------------------------------
1103template < DGtal::Dimension dim, typename TInteger>
1104inline
1105bool
1106DGtal::KhalimskySpaceND< dim, TInteger>::
1107sIsOpen( const SCell & p, DGtal::Dimension k ) const
1108{
1109 return PreCellularGridSpace::sIsOpen( p, k );
1110}
1111
1112//-----------------------------------------------------------------------------
1113///////////////////////////////////////////////////////////////////////////////
1114//-----------------------------------------------------------------------------
1115template < DGtal::Dimension dim, typename TInteger>
1116inline
1117typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1118DGtal::KhalimskySpaceND< dim, TInteger>::
1119uDirs( const Cell & p ) const
1120{
1121 return PreCellularGridSpace::uDirs( p );
1122}
1123//-----------------------------------------------------------------------------
1124template < DGtal::Dimension dim, typename TInteger>
1125inline
1126typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1127DGtal::KhalimskySpaceND< dim, TInteger>::
1128sDirs( const SCell & p ) const
1129{
1130 return PreCellularGridSpace::sDirs( p );
1131}
1132//-----------------------------------------------------------------------------
1133template < DGtal::Dimension dim, typename TInteger>
1134inline
1135typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1136DGtal::KhalimskySpaceND< dim, TInteger>::
1137uOrthDirs( const Cell & p ) const
1138{
1139 return PreCellularGridSpace::uOrthDirs( p );
1140}
1141//-----------------------------------------------------------------------------
1142template < DGtal::Dimension dim, typename TInteger>
1143inline
1144typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1145DGtal::KhalimskySpaceND< dim, TInteger>::
1146sOrthDirs( const SCell & p ) const
1147{
1148 return PreCellularGridSpace::sOrthDirs( p );
1149}
1150//-----------------------------------------------------------------------------
1151template < DGtal::Dimension dim, typename TInteger>
1152inline
1153DGtal::Dimension
1154DGtal::KhalimskySpaceND< dim, TInteger>::
1155uOrthDir( const Cell & s ) const
1156{
1157 return PreCellularGridSpace::uOrthDir( s );
1158}
1159//-----------------------------------------------------------------------------
1160template < DGtal::Dimension dim, typename TInteger>
1161inline
1162DGtal::Dimension
1163DGtal::KhalimskySpaceND< dim, TInteger>::
1164sOrthDir( const SCell & s ) const
1165{
1166 return PreCellularGridSpace::sOrthDir( s );
1167}
1168//-----------------------------------------------------------------------------
1169///////////////////////////////////////////////////////////////////////////////
1170//-----------------------------------------------------------------------------
1171//-----------------------------------------------------------------------------
1172template < DGtal::Dimension dim, typename TInteger>
1173inline
1174typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1175DGtal::KhalimskySpaceND< dim, TInteger>::
1176uFirst( const PreCell & p, DGtal::Dimension k ) const
1177{
1178 ASSERT( k < DIM );
1179
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 );
1183}
1184//-----------------------------------------------------------------------------
1185template < DGtal::Dimension dim, typename TInteger>
1186inline
1187typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1188DGtal::KhalimskySpaceND< dim, TInteger>::
1189uFirst( const PreCell & p ) const
1190{
1191 Cell cell;
1192 for ( Dimension k = 0; k < dimension; ++k )
1193 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uFirst( p, k ) );
1194
1195 return cell;
1196}
1197//-----------------------------------------------------------------------------
1198template < DGtal::Dimension dim, typename TInteger>
1199inline
1200typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1201DGtal::KhalimskySpaceND< dim, TInteger>::
1202uLast( const PreCell & p, DGtal::Dimension k ) const
1203{
1204 ASSERT( k < DIM );
1205
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 );
1209}
1210//-----------------------------------------------------------------------------
1211template < DGtal::Dimension dim, typename TInteger>
1212inline
1213typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1214DGtal::KhalimskySpaceND< dim, TInteger>::
1215uLast( const PreCell & p ) const
1216{
1217 Cell cell;
1218 for ( Dimension k = 0; k < dimension; ++k )
1219 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uLast( p, k ) );
1220
1221 return cell;
1222}
1223//-----------------------------------------------------------------------------
1224template < DGtal::Dimension dim, typename TInteger>
1225inline
1226typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1227DGtal::KhalimskySpaceND< dim, TInteger>::
1228uGetIncr( const Cell & p, DGtal::Dimension k ) const
1229{
1230 Cell cell( PreCellularGridSpace::uGetIncr( p, k ) );
1231 this->updateCellHelper( cell, k );
1232 ASSERT( uIsValid(cell) );
1233 return cell;
1234}
1235//-----------------------------------------------------------------------------
1236template < DGtal::Dimension dim, typename TInteger>
1237inline
1238bool
1239DGtal::KhalimskySpaceND< dim, TInteger>::
1240uIsMax( const Cell & p, DGtal::Dimension k ) const
1241{
1242 ASSERT( k < DIM );
1243 ASSERT( uIsInside(p) );
1244 return
1245 ! this->isDimensionPeriodicHelper( k )
1246 && PreCellularGridSpace::uKCoord( p, k ) >= uLast( p, k );
1247}
1248//-----------------------------------------------------------------------------
1249template < DGtal::Dimension dim, typename TInteger>
1250inline
1251bool
1252DGtal::KhalimskySpaceND< dim, TInteger>::
1253uIsInside( const PreCell & p, DGtal::Dimension k ) const
1254{
1255 return cIsInside( p.coordinates, k );
1256}
1257//-----------------------------------------------------------------------------
1258template < DGtal::Dimension dim, typename TInteger>
1259inline
1260bool
1261DGtal::KhalimskySpaceND< dim, TInteger>::
1262uIsInside( const PreCell & p ) const
1263{
1264 return cIsInside( p.coordinates );
1265}
1266//-----------------------------------------------------------------------------
1267template < DGtal::Dimension dim, typename TInteger>
1268inline
1269bool
1270DGtal::KhalimskySpaceND< dim, TInteger>::
1271cIsInside( const Point & p, DGtal::Dimension k ) const
1272{
1273 ASSERT( k < DIM );
1274 return this->isDimensionPeriodicHelper( k )
1275 || cIsValid( p, k );
1276}
1277//-----------------------------------------------------------------------------
1278template < DGtal::Dimension dim, typename TInteger>
1279inline
1280bool
1281DGtal::KhalimskySpaceND< dim, TInteger>::
1282cIsInside( const Point & p ) const
1283{
1284 for ( Dimension k = 0; k < DIM; ++k )
1285 if ( ! cIsInside( p, k ) )
1286 return false;
1287
1288 return true;
1289}
1290//-----------------------------------------------------------------------------
1291template < DGtal::Dimension dim, typename TInteger>
1292inline
1293typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1294DGtal::KhalimskySpaceND< dim, TInteger>::
1295uGetMax( Cell p, DGtal::Dimension k ) const
1296{
1297 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uLast( p, k ) );
1298 ASSERT( uIsValid( p ) );
1299 return p;
1300}
1301//-----------------------------------------------------------------------------
1302template < DGtal::Dimension dim, typename TInteger>
1303inline
1304typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1305DGtal::KhalimskySpaceND< dim, TInteger>::
1306uGetDecr( const Cell & p, DGtal::Dimension k ) const
1307{
1308 Cell cell( PreCellularGridSpace::uGetDecr( p, k ) );
1309 this->updateCellHelper( cell, k );
1310 ASSERT( uIsValid( cell ) );
1311 return cell;
1312}
1313//-----------------------------------------------------------------------------
1314template < DGtal::Dimension dim, typename TInteger>
1315inline
1316bool
1317DGtal::KhalimskySpaceND< dim, TInteger>::
1318uIsMin( const Cell & p, DGtal::Dimension k ) const
1319{
1320 ASSERT( uIsInside(p) );
1321 return
1322 ! this->isDimensionPeriodicHelper( k )
1323 && PreCellularGridSpace::uKCoord( p, k ) <= uFirst( p, k );
1324}
1325//-----------------------------------------------------------------------------
1326template < DGtal::Dimension dim, typename TInteger>
1327inline
1328typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1329DGtal::KhalimskySpaceND< dim, TInteger>::
1330uGetMin( Cell p, DGtal::Dimension k ) const
1331{
1332 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uFirst( p, k ) );
1333 ASSERT( uIsValid(p) );
1334 return p;
1335}
1336//-----------------------------------------------------------------------------
1337template < DGtal::Dimension dim, typename TInteger>
1338inline
1339typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1340DGtal::KhalimskySpaceND< dim, TInteger>::
1341uGetAdd( const Cell & p, DGtal::Dimension k, Integer x ) const
1342{
1343 Cell cell( PreCellularGridSpace::uGetAdd( p, k, x ) );
1344 this->updateCellHelper( cell, k );
1345 ASSERT( uIsValid( cell ) );
1346 return cell;
1347}
1348//-----------------------------------------------------------------------------
1349template < DGtal::Dimension dim, typename TInteger>
1350inline
1351typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1352DGtal::KhalimskySpaceND< dim, TInteger>::
1353uGetSub( const Cell & p, DGtal::Dimension k, Integer x ) const
1354{
1355 Cell cell( PreCellularGridSpace::uGetSub( p, k, x ) );
1356 this->updateCellHelper( cell, k );
1357 ASSERT( uIsValid( cell ) );
1358 return cell;
1359}
1360//-----------------------------------------------------------------------------
1361template < DGtal::Dimension dim, typename TInteger>
1362inline
1363TInteger
1364DGtal::KhalimskySpaceND< dim, TInteger>::
1365uDistanceToMax( const Cell & p, DGtal::Dimension k ) const
1366{
1367 using KPS = PreCellularGridSpace;
1368 ASSERT( k < DIM );
1369 ASSERT( uIsValid(p) );
1370 return ( KPS::uKCoord( myCellUpper, k ) - KPS::uKCoord( p, k ) ) >> 1;
1371}
1372//-----------------------------------------------------------------------------
1373template < DGtal::Dimension dim, typename TInteger>
1374inline
1375TInteger
1376DGtal::KhalimskySpaceND< dim, TInteger>::
1377uDistanceToMin( const Cell & p, DGtal::Dimension k ) const
1378{
1379 using KPS = PreCellularGridSpace;
1380 ASSERT( k < DIM );
1381 ASSERT( uIsValid(p) );
1382 return ( KPS::uKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1383}
1384//-----------------------------------------------------------------------------
1385template < DGtal::Dimension dim, typename TInteger>
1386inline
1387typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1388DGtal::KhalimskySpaceND< dim, TInteger>::
1389uTranslation( const Cell & p, const Vector & vec ) const
1390{
1391 Cell cell( PreCellularGridSpace::uTranslation( p, vec ) );
1392 this->updateCellHelper( cell );
1393 ASSERT( uIsValid( cell ) );
1394 return cell;
1395}
1396//-----------------------------------------------------------------------------
1397template < DGtal::Dimension dim, typename TInteger>
1398inline
1399typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1400DGtal::KhalimskySpaceND< dim, TInteger>::
1401uProjection( const Cell & p, const Cell & bound, DGtal::Dimension k ) const
1402{
1403 Cell cell( PreCellularGridSpace::uProjection( p, bound, k ) );
1404 ASSERT( uIsValid( cell ) );
1405 return cell;
1406}
1407//-----------------------------------------------------------------------------
1408template < DGtal::Dimension dim, typename TInteger>
1409inline
1410void
1411DGtal::KhalimskySpaceND< dim, TInteger>::
1412uProject( Cell & p, const Cell & bound, DGtal::Dimension k ) const
1413{
1414 PreCellularGridSpace::uProject( p.myPreCell, bound, k );
1415 ASSERT( uIsValid( p ) );
1416}
1417//-----------------------------------------------------------------------------
1418template < DGtal::Dimension dim, typename TInteger>
1419inline
1420bool
1421DGtal::KhalimskySpaceND< dim, TInteger>::
1422uNext( Cell & p, const Cell & lower, const Cell & upper ) const
1423{
1424 ASSERT( uIsValid(p) );
1425 ASSERT( uIsValid(lower) );
1426 ASSERT( uIsValid(upper) );
1427 ASSERT( uTopology(p) == uTopology(lower)
1428 && uTopology(p) == uTopology(upper) );
1429
1430 using KPS = PreCellularGridSpace;
1431
1432 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1433 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1434 {
1435 if ( p == upper ) return false;
1436 KPS::uProject( p.myPreCell, lower, k );
1437
1438 for ( k = 1; k < DIM; ++k )
1439 {
1440 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1441 KPS::uProject( p.myPreCell, lower, k );
1442 else
1443 {
1444 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1445 break;
1446 }
1447 }
1448 return true;
1449 }
1450
1451 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1452 return true;
1453}
1454
1455//-----------------------------------------------------------------------------
1456///////////////////////////////////////////////////////////////////////////////
1457//-----------------------------------------------------------------------------
1458//-----------------------------------------------------------------------------
1459template < DGtal::Dimension dim, typename TInteger>
1460inline
1461typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1462DGtal::KhalimskySpaceND< dim, TInteger>::
1463sFirst( const SPreCell & p, DGtal::Dimension k ) const
1464{
1465 ASSERT( k < DIM );
1466
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 );
1470}
1471//-----------------------------------------------------------------------------
1472template < DGtal::Dimension dim, typename TInteger>
1473inline
1474typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1475DGtal::KhalimskySpaceND< dim, TInteger >::
1476sFirst( const SPreCell & p ) const
1477{
1478 SCell cell;
1479 for ( Dimension k = 0; k < dimension; ++k )
1480 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sFirst( p, k ) );
1481
1482 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1483
1484 return cell;
1485}
1486//-----------------------------------------------------------------------------
1487template < DGtal::Dimension dim, typename TInteger>
1488inline
1489typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1490DGtal::KhalimskySpaceND< dim, TInteger>::
1491sLast( const SPreCell & p, DGtal::Dimension k ) const
1492{
1493 ASSERT( k < DIM );
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 );
1497}
1498//-----------------------------------------------------------------------------
1499template < DGtal::Dimension dim, typename TInteger>
1500inline
1501typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1502DGtal::KhalimskySpaceND< dim, TInteger >::
1503sLast( const SPreCell & p ) const
1504{
1505 SCell cell;
1506 for ( Dimension k = 0; k < dimension; ++k )
1507 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sLast( p, k ) );
1508
1509 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1510
1511 return cell;
1512}
1513//-----------------------------------------------------------------------------
1514template < DGtal::Dimension dim, typename TInteger>
1515inline
1516typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1517DGtal::KhalimskySpaceND< dim, TInteger >::
1518sGetIncr( const SCell & p, DGtal::Dimension k ) const
1519{
1520 SCell cell( PreCellularGridSpace::sGetIncr( p, k ) );
1521 this->updateSCellHelper( cell, k );
1522 ASSERT( sIsValid( cell ) );
1523 return cell;
1524}
1525//-----------------------------------------------------------------------------
1526template < DGtal::Dimension dim, typename TInteger>
1527inline
1528bool
1529DGtal::KhalimskySpaceND< dim, TInteger >::
1530sIsMax( const SCell & p, DGtal::Dimension k ) const
1531{
1532 ASSERT( k < DIM );
1533 ASSERT( sIsInside(p) );
1534 return
1535 ! this->isDimensionPeriodicHelper( k )
1536 && PreCellularGridSpace::sKCoord( p, k ) >= sLast( p, k );
1537}
1538//-----------------------------------------------------------------------------
1539template < DGtal::Dimension dim, typename TInteger>
1540inline
1541bool
1542DGtal::KhalimskySpaceND< dim, TInteger>::
1543sIsInside( const SPreCell & p, DGtal::Dimension k ) const
1544{
1545 return cIsInside( p.coordinates, k );
1546}
1547//-----------------------------------------------------------------------------
1548template < DGtal::Dimension dim, typename TInteger>
1549inline
1550bool
1551DGtal::KhalimskySpaceND< dim, TInteger>::
1552sIsInside( const SPreCell & p ) const
1553{
1554 return cIsInside( p.coordinates );
1555}
1556//-----------------------------------------------------------------------------
1557template < DGtal::Dimension dim, typename TInteger>
1558inline
1559typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1560DGtal::KhalimskySpaceND< dim, TInteger >::
1561sGetMax( SCell p, DGtal::Dimension k ) const
1562{
1563 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sLast( p, k ) );
1564 ASSERT( sIsValid( p ) );
1565 return p;
1566}
1567//-----------------------------------------------------------------------------
1568template < DGtal::Dimension dim, typename TInteger>
1569inline
1570typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1571DGtal::KhalimskySpaceND< dim, TInteger >::
1572sGetDecr( const SCell & p, DGtal::Dimension k ) const
1573{
1574 SCell cell( PreCellularGridSpace::sGetDecr( p, k ) );
1575 this->updateSCellHelper( cell, k );
1576 ASSERT( sIsValid( cell ) );
1577 return cell;
1578}
1579//-----------------------------------------------------------------------------
1580template < DGtal::Dimension dim, typename TInteger>
1581inline
1582bool
1583DGtal::KhalimskySpaceND< dim, TInteger >::
1584sIsMin( const SCell & p, DGtal::Dimension k ) const
1585{
1586 ASSERT( k < DIM );
1587 ASSERT( sIsInside(p) );
1588 return
1589 ! this->isDimensionPeriodicHelper( k )
1590 && PreCellularGridSpace::sKCoord( p, k ) <= sFirst( p, k );
1591}
1592//-----------------------------------------------------------------------------
1593template < DGtal::Dimension dim, typename TInteger>
1594inline
1595typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1596DGtal::KhalimskySpaceND< dim, TInteger >::
1597sGetMin( SCell p, DGtal::Dimension k ) const
1598{
1599 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sFirst( p, k ) );
1600 ASSERT( sIsValid( p ) );
1601 return p;
1602}
1603//-----------------------------------------------------------------------------
1604template < DGtal::Dimension dim, typename TInteger>
1605inline
1606typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1607DGtal::KhalimskySpaceND< dim, TInteger >::
1608sGetAdd( const SCell & p, DGtal::Dimension k, Integer x ) const
1609{
1610 SCell cell( PreCellularGridSpace::sGetAdd( p, k, x ) );
1611 this->updateSCellHelper( cell, k );
1612 ASSERT( sIsValid( cell ) );
1613 return cell;
1614}
1615//-----------------------------------------------------------------------------
1616template < DGtal::Dimension dim, typename TInteger>
1617inline
1618typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1619DGtal::KhalimskySpaceND< dim, TInteger >::
1620sGetSub( const SCell & p, DGtal::Dimension k, Integer x ) const
1621{
1622 SCell cell( PreCellularGridSpace::sGetSub( p, k, x ) );
1623 this->updateSCellHelper( cell, k );
1624 ASSERT( sIsValid( cell ) );
1625 return cell;
1626}
1627//-----------------------------------------------------------------------------
1628template < DGtal::Dimension dim, typename TInteger>
1629inline
1630TInteger
1631DGtal::KhalimskySpaceND< dim, TInteger >::
1632sDistanceToMax( const SCell & p, DGtal::Dimension k ) const
1633{
1634 using KPS = PreCellularGridSpace;
1635 ASSERT( k < DIM );
1636 ASSERT( sIsValid( p ) );
1637 return ( KPS::uKCoord( myCellUpper, k ) - KPS::sKCoord( p, k ) ) >> 1;
1638}
1639//-----------------------------------------------------------------------------
1640template < DGtal::Dimension dim, typename TInteger>
1641inline
1642TInteger
1643DGtal::KhalimskySpaceND< dim, TInteger >::
1644sDistanceToMin( const SCell & p, DGtal::Dimension k ) const
1645{
1646 using KPS = PreCellularGridSpace;
1647 ASSERT( k < DIM );
1648 ASSERT( sIsValid( p ) );
1649 return ( KPS::sKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1650}
1651//-----------------------------------------------------------------------------
1652template < DGtal::Dimension dim, typename TInteger>
1653inline
1654typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1655DGtal::KhalimskySpaceND< dim, TInteger >::
1656sTranslation( const SCell & p, const Vector & vec ) const
1657{
1658 SCell cell( PreCellularGridSpace::sTranslation( p, vec ) );
1659 this->updateSCellHelper( cell );
1660 ASSERT( sIsValid( cell ) );
1661 return cell;
1662}
1663//-----------------------------------------------------------------------------
1664template < DGtal::Dimension dim, typename TInteger>
1665inline
1666typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1667DGtal::KhalimskySpaceND< dim, TInteger >::
1668sProjection( const SCell & p, const SCell & bound, DGtal::Dimension k ) const
1669{
1670 SCell cell( PreCellularGridSpace::sProjection( p, bound, k ) );
1671 ASSERT( sIsValid( cell ) );
1672 return cell;
1673}
1674//-----------------------------------------------------------------------------
1675template < DGtal::Dimension dim, typename TInteger>
1676inline
1677void
1678DGtal::KhalimskySpaceND< dim, TInteger >::
1679sProject( SCell & p, const SCell & bound, DGtal::Dimension k ) const
1680{
1681 PreCellularGridSpace::sProject( p.mySPreCell, bound, k );
1682 ASSERT( sIsValid( p ) );
1683}
1684//-----------------------------------------------------------------------------
1685template < DGtal::Dimension dim, typename TInteger>
1686inline
1687bool
1688DGtal::KhalimskySpaceND< dim, TInteger >::
1689sNext( SCell & p, const SCell & lower, const SCell & upper ) const
1690{
1691 ASSERT( sIsValid(p) );
1692 ASSERT( sIsValid(lower) );
1693 ASSERT( sIsValid(upper) );
1694 ASSERT( sTopology(p) == sTopology(lower)
1695 && sTopology(p) == sTopology(upper) );
1696
1697 using KPS = PreCellularGridSpace;
1698
1699 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1700 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1701 {
1702 if ( p == upper ) return false;
1703 KPS::sProject( p.mySPreCell, lower, k );
1704
1705 for ( k = 1; k < DIM; ++k )
1706 {
1707 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1708 KPS::sProject( p.mySPreCell, lower, k );
1709 else
1710 {
1711 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1712 break;
1713 }
1714 }
1715 return true;
1716 }
1717
1718 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1719 return true;
1720}
1721
1722//-----------------------------------------------------------------------------
1723// ----------------------- Neighborhood services --------------------------
1724//-----------------------------------------------------------------------------
1725template < DGtal::Dimension dim, typename TInteger>
1726inline
1727typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1728DGtal::KhalimskySpaceND< dim, TInteger >::
1729uNeighborhood( const Cell & c ) const
1730{
1731 ASSERT( uIsValid(c) );
1732
1733 Cells N;
1734 N.push_back( c );
1735 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1736 {
1737 if ( ! uIsMin( c, k ) )
1738 N.push_back( uGetDecr( c, k ) );
1739 if ( ! uIsMax( c, k ) )
1740 N.push_back( uGetIncr( c, k ) );
1741 }
1742 return N;
1743}
1744//-----------------------------------------------------------------------------
1745template < DGtal::Dimension dim, typename TInteger>
1746inline
1747typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1748DGtal::KhalimskySpaceND< dim, TInteger >::
1749sNeighborhood( const SCell & c ) const
1750{
1751 ASSERT( sIsValid(c) );
1752
1753 SCells N;
1754 N.push_back( c );
1755 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1756 {
1757 if ( ! sIsMin( c, k ) )
1758 N.push_back( sGetDecr( c, k ) );
1759 if ( ! sIsMax( c, k ) )
1760 N.push_back( sGetIncr( c, k ) );
1761 }
1762 return N;
1763}
1764//-----------------------------------------------------------------------------
1765template < DGtal::Dimension dim, typename TInteger>
1766inline
1767typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1768DGtal::KhalimskySpaceND< dim, TInteger >::
1769uProperNeighborhood( const Cell & c ) const
1770{
1771 ASSERT( uIsValid(c) );
1772
1773 Cells N;
1774 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1775 {
1776 if ( ! uIsMin( c, k ) )
1777 N.push_back( uGetDecr( c, k ) );
1778 if ( ! uIsMax( c, k ) )
1779 N.push_back( uGetIncr( c, k ) );
1780 }
1781 return N;
1782}
1783//-----------------------------------------------------------------------------
1784template < DGtal::Dimension dim, typename TInteger>
1785inline
1786typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1787DGtal::KhalimskySpaceND< dim, TInteger >::
1788sProperNeighborhood( const SCell & c ) const
1789{
1790 ASSERT( sIsValid(c) );
1791
1792 SCells N;
1793 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1794 {
1795 if ( ! sIsMin( c, k ) )
1796 N.push_back( sGetDecr( c, k ) );
1797 if ( ! sIsMax( c, k ) )
1798 N.push_back( sGetIncr( c, k ) );
1799 }
1800 return N;
1801}
1802//-----------------------------------------------------------------------------
1803template < DGtal::Dimension dim, typename TInteger>
1804inline
1805typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1806DGtal::KhalimskySpaceND< dim, TInteger >::
1807uAdjacent( const Cell & p, DGtal::Dimension k, bool up ) const
1808{
1809 ASSERT( k < DIM );
1810 ASSERT( uIsValid(p) );
1811 ASSERT( ( up && !uIsMax(p, k) ) || ( !up && !uIsMin(p, k) ) );
1812 return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1813}
1814//-----------------------------------------------------------------------------
1815template < DGtal::Dimension dim, typename TInteger>
1816inline
1817typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1818DGtal::KhalimskySpaceND< dim, TInteger >::
1819sAdjacent( const SCell & p, DGtal::Dimension k, bool up ) const
1820{
1821 ASSERT( k < DIM );
1822 ASSERT( sIsValid(p) );
1823 ASSERT( ( up && !sIsMax(p, k) ) || ( !up && !sIsMin(p, k) ) );
1824 return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1825}
1826
1827// ----------------------- Incidence services --------------------------
1828//-----------------------------------------------------------------------------
1829template < DGtal::Dimension dim, typename TInteger>
1830inline
1831typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1832DGtal::KhalimskySpaceND< dim, TInteger >::
1833uIncident( const Cell & c, DGtal::Dimension k, bool up ) const
1834{
1835 ASSERT( k < dim );
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 ) ) );
1839
1840 Cell cell( PreCellularGridSpace::uIncident( c, k, up ) );
1841 this->updateCellHelper( cell, k );
1842
1843 return cell;
1844}
1845//-----------------------------------------------------------------------------
1846template < DGtal::Dimension dim, typename TInteger>
1847inline
1848typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1849DGtal::KhalimskySpaceND< dim, TInteger >::
1850sIncident( const SCell & c, DGtal::Dimension k, bool up ) const
1851{
1852 ASSERT( k < dim );
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 ) ) );
1856
1857 SCell cell( PreCellularGridSpace::sIncident( c, k, up ) );
1858 this->updateSCellHelper( cell, k );
1859
1860 return cell;
1861}
1862//-----------------------------------------------------------------------------
1863template < DGtal::Dimension dim, typename TInteger>
1864inline
1865typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1866DGtal::KhalimskySpaceND< dim, TInteger >::
1867uLowerIncident( const Cell & c ) const
1868{
1869 ASSERT( uIsValid(c) );
1870
1871 Cells N;
1872 for ( DirIterator q = uDirs( c ); q != 0; ++q )
1873 {
1874 const DGtal::Dimension k = *q;
1875 if ( this->isDimensionPeriodicHelper( k ) )
1876 {
1877 N.push_back( uIncident( c, k, false ) );
1878 N.push_back( uIncident( c, k, true ) );
1879 }
1880 else
1881 {
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 ) );
1887 }
1888 }
1889 return N;
1890}
1891//-----------------------------------------------------------------------------
1892template < DGtal::Dimension dim, typename TInteger>
1893inline
1894typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1895DGtal::KhalimskySpaceND< dim, TInteger >::
1896uUpperIncident( const Cell & c ) const
1897{
1898 ASSERT( uIsValid(c) );
1899
1900 Cells N;
1901 for ( DirIterator q = uOrthDirs( c ); q != 0; ++q )
1902 {
1903 const DGtal::Dimension k = *q;
1904 if ( this->isDimensionPeriodicHelper( k ) )
1905 {
1906 N.push_back( uIncident( c, k, false ) );
1907 N.push_back( uIncident( c, k, true ) );
1908 }
1909 else
1910 {
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 ) );
1916 }
1917 }
1918 return N;
1919}
1920//-----------------------------------------------------------------------------
1921template < DGtal::Dimension dim, typename TInteger>
1922inline
1923typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1924DGtal::KhalimskySpaceND< dim, TInteger >::
1925sLowerIncident( const SCell & c ) const
1926{
1927 ASSERT( sIsValid(c) );
1928
1929 SCells N;
1930 for ( DirIterator q = sDirs( c ); q != 0; ++q )
1931 {
1932 const DGtal::Dimension k = *q;
1933 if ( this->isDimensionPeriodicHelper( k ) )
1934 {
1935 N.push_back( sIncident( c, k, false ) );
1936 N.push_back( sIncident( c, k, true ) );
1937 }
1938 else
1939 {
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 ) );
1945 }
1946 }
1947 return N;
1948}
1949//-----------------------------------------------------------------------------
1950template < DGtal::Dimension dim, typename TInteger>
1951inline
1952typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1953DGtal::KhalimskySpaceND< dim, TInteger >::
1954sUpperIncident( const SCell & c ) const
1955{
1956 ASSERT( sIsValid(c) );
1957
1958 SCells N;
1959 for ( DirIterator q = sOrthDirs( c ); q != 0; ++q )
1960 {
1961 const DGtal::Dimension k = *q;
1962 if ( this->isDimensionPeriodicHelper( k ) )
1963 {
1964 N.push_back( sIncident( c, k, false ) );
1965 N.push_back( sIncident( c, k, true ) );
1966 }
1967 else
1968 {
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 ) );
1974 }
1975 }
1976 return N;
1977}
1978//-----------------------------------------------------------------------------
1979template < DGtal::Dimension dim, typename TInteger>
1980inline
1981void
1982DGtal::KhalimskySpaceND< dim, TInteger >::
1983uAddFaces( Cells& faces, const Cell& c, Dimension axis ) const
1984{
1985 using KPS = PreCellularGridSpace;
1986
1987 const DGtal::Dimension dim_of_c = uDim( c );
1988 if ( axis >= dim_of_c ) return;
1989
1990 DirIterator q = uDirs( c );
1991 for ( Dimension i = 0; i < axis; ++i ) ++q;
1992
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 ) ;
1997
1998 Cell f1, f2;
1999 if ( has_f1 ) f1 = uIncident( c, *q, false );
2000 if ( has_f2 ) f2 = uIncident( c, *q, true );
2001
2002 if ( has_f1 ) faces.push_back( f1 );
2003 if ( has_f2 ) faces.push_back( f2 );
2004
2005 if ( has_f1 ) uAddFaces( faces, f1, axis );
2006 if ( has_f2 ) uAddFaces( faces, f2, axis );
2007
2008 uAddFaces( faces, c, axis+1 );
2009}
2010//-----------------------------------------------------------------------------
2011template < DGtal::Dimension dim, typename TInteger>
2012inline
2013void
2014DGtal::KhalimskySpaceND< dim, TInteger >::
2015uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis ) const
2016{
2017 using KPS = PreCellularGridSpace;
2018
2019 const DGtal::Dimension dim_of_c = uDim( c );
2020 if ( axis >= dimension - dim_of_c ) return;
2021
2022 DirIterator q = uOrthDirs( c );
2023 for ( Dimension i = 0; i < axis; ++i ) ++q;
2024
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 ) ;
2029
2030 Cell f1, f2;
2031 if ( has_f1 ) f1 = uIncident( c, *q, false );
2032 if ( has_f2 ) f2 = uIncident( c, *q, true );
2033
2034 if ( has_f1 ) cofaces.push_back( f1 );
2035 if ( has_f2 ) cofaces.push_back( f2 );
2036
2037 if ( has_f1 ) uAddCoFaces( cofaces, f1, axis );
2038 if ( has_f2 ) uAddCoFaces( cofaces, f2, axis );
2039
2040 uAddCoFaces( cofaces, c, axis+1 );
2041}
2042//-----------------------------------------------------------------------------
2043template < DGtal::Dimension dim, typename TInteger>
2044inline
2045typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2046DGtal::KhalimskySpaceND< dim, TInteger >::
2047uFaces( const Cell & c ) const
2048{
2049 ASSERT( uIsValid(c) );
2050
2051 Cells N;
2052 uAddFaces( N, c, 0 );
2053 return N;
2054}
2055//-----------------------------------------------------------------------------
2056template < DGtal::Dimension dim, typename TInteger>
2057inline
2058typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2059DGtal::KhalimskySpaceND< dim, TInteger >::
2060uCoFaces( const Cell & c ) const
2061{
2062 ASSERT( uIsValid(c) );
2063
2064 Cells N;
2065 uAddCoFaces( N, c, 0 );
2066 return N;
2067}
2068//-----------------------------------------------------------------------------
2069template < DGtal::Dimension dim, typename TInteger>
2070inline
2071bool
2072DGtal::KhalimskySpaceND< dim, TInteger >::
2073sDirect( const SCell & p, DGtal::Dimension k ) const
2074{
2075 return PreCellularGridSpace::sDirect( p, k );
2076}
2077//-----------------------------------------------------------------------------
2078template < DGtal::Dimension dim, typename TInteger>
2079inline
2080typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2081DGtal::KhalimskySpaceND< dim, TInteger >::
2082sDirectIncident( const SCell & p, DGtal::Dimension k ) const
2083{
2084 using KPS = PreCellularGridSpace;
2085
2086 ASSERT( k < dim );
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 ) ) );
2090
2091 SCell cell( KPS::sDirectIncident( p, k ) );
2092 this->updateSCellHelper( cell, k );
2093
2094 return cell;
2095}
2096//-----------------------------------------------------------------------------
2097template < DGtal::Dimension dim, typename TInteger>
2098inline
2099typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2100DGtal::KhalimskySpaceND< dim, TInteger >::
2101sIndirectIncident( const SCell & p, DGtal::Dimension k ) const
2102{
2103 using KPS = PreCellularGridSpace;
2104
2105 ASSERT( k < dim );
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 ) ) );
2109
2110 SCell cell( KPS::sIndirectIncident( p, k ) );
2111 this->updateSCellHelper( cell, k );
2112
2113 return cell;
2114}
2115
2116
2117
2118
2119//-----------------------------------------------------------------------------
2120template < DGtal::Dimension dim, typename TInteger>
2121inline
2122void
2123DGtal::KhalimskySpaceND< dim, TInteger>::
2124selfDisplay ( std::ostream & out ) const
2125{
2126 out << "[KhalimskySpaceND<" << dimension << ">] { ";
2127 out << "{ ";
2128 for ( Dimension i = 0; i < dimension; ++i )
2129 out << ( myClosure[i] == OPEN ? "OPEN " : ( myClosure[i] == CLOSED ? "CLOSED " : "PERIODIC " ) );
2130 out << "}, ";
2131 out << "lower = " << myLower << ", ";
2132 out << "upper = " << myUpper;
2133 out << " }";
2134
2135}
2136//-----------------------------------------------------------------------------
2137template < DGtal::Dimension dim, typename TInteger>
2138inline
2139bool
2140DGtal::KhalimskySpaceND< dim, TInteger>::
2141isValid() const
2142{
2143 return true;
2144}
2145
2146
2147
2148///////////////////////////////////////////////////////////////////////////////
2149// Implementation of inline functions //
2150template < DGtal::Dimension dim, typename TInteger>
2151inline
2152std::ostream&
2153DGtal::operator<< ( std::ostream & out,
2154 const KhalimskySpaceND< dim, TInteger> & object )
2155{
2156 object.selfDisplay( out );
2157 return out;
2158}
2159
2160// //
2161///////////////////////////////////////////////////////////////////////////////