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 CellGeometry.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in CellGeometry.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
35 //////////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////////
38 // IMPLEMENTATION of inline methods.
39 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 // ----------------------- Standard services ------------------------------
44 //-----------------------------------------------------------------------------
45 template <typename TKSpace>
46 DGtal::CellGeometry<TKSpace>::
49 myMinCellDim( 0 ), myMaxCellDim( KSpace::dimension ),
54 //-----------------------------------------------------------------------------
55 template <typename TKSpace>
56 DGtal::CellGeometry<TKSpace>::
57 CellGeometry( const KSpace & K,
58 Dimension min_cell_dim, Dimension max_cell_dim, bool verbose )
59 : myK( K ), myKPoints(),
60 myMinCellDim( min_cell_dim ), myMaxCellDim( max_cell_dim ),
63 ASSERT( myMinCellDim <= myMaxCellDim );
64 ASSERT( myMaxCellDim <= myK.dimension );
66 //-----------------------------------------------------------------------------
67 template <typename TKSpace>
69 DGtal::CellGeometry<TKSpace>::
70 init( const KSpace & K,
71 Dimension min_cell_dim, Dimension max_cell_dim, bool verbose )
73 ASSERT( myMinCellDim <= myMaxCellDim );
74 ASSERT( myMaxCellDim <= myK.dimension );
77 myMinCellDim = min_cell_dim;
78 myMaxCellDim = max_cell_dim;
82 //-----------------------------------------------------------------------------
83 template <typename TKSpace>
85 DGtal::CellGeometry<TKSpace>::
86 addCellsTouchingPoint( const Point& p )
88 addCellsTouchingPointel( myK.uPointel( p ) );
91 //-----------------------------------------------------------------------------
92 template <typename TKSpace>
94 DGtal::CellGeometry<TKSpace>::
95 addCellsTouchingPointel( const Cell& pointel )
97 auto cofaces = myK.uCoFaces( pointel );
98 if ( ( myMinCellDim == 0 ) && ( myMaxCellDim == KSpace::dimension ) )
100 myKPoints.emplace( myK.uKCoords( pointel ) );
101 for ( auto && c : cofaces )
102 myKPoints.emplace( myK.uKCoords( c ) );
106 if ( myMinCellDim <= 0 )
107 myKPoints.emplace( myK.uKCoords( pointel ) );
108 for ( auto&& f : cofaces )
110 Dimension d = myK.uDim( f );
111 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
112 myKPoints.emplace( myK.uKCoords( f ) );
117 //-----------------------------------------------------------------------------
118 template <typename TKSpace>
120 DGtal::CellGeometry<TKSpace>::
121 addCellsTouchingCell( const Cell& c )
123 const Dimension dc = myK.uDim( c );
124 if ( myMinCellDim <= dc && dc <= myMaxCellDim )
125 myKPoints.emplace( myK.uKCoords( c ) );
126 if ( myMaxCellDim <= dc ) return;
127 const auto cofaces = myK.uCoFaces( c );
128 for ( auto&& f : cofaces )
130 Dimension d = myK.uDim( f );
131 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
132 myKPoints.emplace( myK.uKCoords( f ) );
136 //-----------------------------------------------------------------------------
137 template <typename TKSpace>
139 DGtal::CellGeometry<TKSpace>::
140 addCellsTouchingSegment( const Point& a, const Point& b )
142 const auto V = b - a;
143 addCellsTouchingPoint( a );
144 for ( Dimension k = 0; k < dimension; k++ )
146 const Integer n = ( V[ k ] >= 0 ) ? V[ k ] : -V[ k ];
147 const Integer d = ( V[ k ] >= 0 ) ? 1 : -1;
148 if ( n == 0 ) continue;
150 for ( Integer i = 1; i < n; i++ )
152 for ( Dimension j = 0; j < dimension; j++ )
154 if ( j == k ) kc[ k ] = 2 * ( a[ k ] + d * i );
157 const auto v = V[ j ];
158 const auto q = ( v * i ) / n;
159 const auto r = ( v * i ) % n; // might be negative
160 kc[ j ] = 2 * ( a[ j ] + q );
161 if ( r < 0 ) kc[ j ] -= 1;
162 else if ( r > 0 ) kc[ j ] += 1;
165 addCellsTouchingCell( myK.uCell( kc ) );
168 if ( a != b ) addCellsTouchingPoint( b );
171 //-----------------------------------------------------------------------------
172 template <typename TKSpace>
173 template <typename PointIterator>
175 DGtal::CellGeometry<TKSpace>::
176 addCellsTouchingPoints( PointIterator itB, PointIterator itE )
178 if ( ( myMinCellDim == 0 ) && ( myMaxCellDim == KSpace::dimension ) )
180 for ( auto it = itB; it != itE; ++it )
182 auto pointel = myK.uPointel( *it );
183 auto cofaces = myK.uCoFaces( pointel );
184 myKPoints.emplace( myK.uKCoords( pointel ) );
185 for ( auto && c : cofaces )
186 myKPoints.emplace( myK.uKCoords( c ) );
191 for ( auto it = itB; it != itE; ++it )
193 auto pointel = myK.uPointel( *it );
194 auto cofaces = myK.uCoFaces( pointel );
195 if ( myMinCellDim <= 0 )
196 myKPoints.emplace( myK.uKCoords( pointel ) );
197 for ( auto&& f : cofaces )
199 Dimension d = myK.uDim( f );
200 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
201 myKPoints.emplace( myK.uKCoords( f ) );
207 //-----------------------------------------------------------------------------
208 template <typename TKSpace>
209 template <typename PointelIterator>
211 DGtal::CellGeometry<TKSpace>::
212 addCellsTouchingPointels( PointelIterator itB, PointelIterator itE )
214 if ( ( myMinCellDim == 0 ) && ( myMaxCellDim == KSpace::dimension ) )
216 for ( auto it = itB; it != itE; ++it )
219 auto cofaces = myK.uCoFaces( pointel );
220 myKPoints.emplace( myK.uKCoords( pointel ) );
221 for ( auto && c : cofaces )
222 myKPoints.emplace( myK.uKCoords( c ) );
227 for ( auto it = itB; it != itE; ++it )
230 auto cofaces = myK.uCoFaces( pointel );
231 if ( myMinCellDim <= 0 )
232 myKPoints.emplace( myK.uKCoords( pointel ) );
233 for ( auto&& f : cofaces )
235 Dimension d = myK.uDim( f );
236 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
237 myKPoints.emplace( myK.uKCoords( f ) );
242 //-----------------------------------------------------------------------------
243 template <typename TKSpace>
245 DGtal::CellGeometry<TKSpace>::
246 addCellsTouchingPolytopePoints( const LatticePolytope& polytope )
248 std::vector< Point > points;
249 polytope.getPoints( points );
250 addCellsTouchingPoints( points.begin(), points.end() );
252 //-----------------------------------------------------------------------------
253 template <typename TKSpace>
255 DGtal::CellGeometry<TKSpace>::
256 addCellsTouchingPolytopePoints( const RationalPolytope& polytope )
258 std::vector< Point > points;
259 polytope.getPoints( points );
260 addCellsTouchingPoints( points.cbegin(), points.cend() );
262 //-----------------------------------------------------------------------------
263 template <typename TKSpace>
265 DGtal::CellGeometry<TKSpace>::
266 addCellsTouchingPolytope( const LatticePolytope& polytope )
268 for ( Dimension i = myMinCellDim; i <= myMaxCellDim; ++i )
270 auto kpoints = getIntersectedKPoints( polytope, i );
271 myKPoints.insert( kpoints.cbegin(), kpoints.cend() );
274 //-----------------------------------------------------------------------------
275 template <typename TKSpace>
277 DGtal::CellGeometry<TKSpace>::
278 addCellsTouchingPolytope( const RationalPolytope& polytope )
280 for ( Dimension i = myMinCellDim; i <= myMaxCellDim; ++i )
282 auto kpoints = getIntersectedKPoints( polytope, i );
283 myKPoints.insert( kpoints.cbegin(), kpoints.cend() );
286 //-----------------------------------------------------------------------------
287 template <typename TKSpace>
288 typename DGtal::CellGeometry<TKSpace>&
289 DGtal::CellGeometry<TKSpace>::
290 operator+=( const CellGeometry& other )
292 if ( this != &other )
294 myKPoints.insert( other.myKPoints.cbegin(), other.myKPoints.cend() );
295 myMinCellDim = std::min( myMinCellDim, other.myMinCellDim );
296 myMaxCellDim = std::max( myMaxCellDim, other.myMaxCellDim );
301 //-----------------------------------------------------------------------------
302 template <typename TKSpace>
303 typename DGtal::CellGeometry<TKSpace>::Size
304 DGtal::CellGeometry<TKSpace>::
307 return (DGtal::CellGeometry<TKSpace>::Size)myKPoints.size();
309 //-----------------------------------------------------------------------------
310 template <typename TKSpace>
311 typename DGtal::CellGeometry<TKSpace>::Size
312 DGtal::CellGeometry<TKSpace>::
313 computeNbCells( const Dimension k ) const
315 if ( k < minCellDim() || k > maxCellDim() ) return 0;
317 for ( auto&& c : myKPoints )
318 nb += ( dim( c ) == k ) ? 1 : 0;
322 //-----------------------------------------------------------------------------
323 template <typename TKSpace>
324 std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
325 DGtal::CellGeometry<TKSpace>::
326 getKPoints( const Dimension k ) const
328 std::vector< Point > R;
329 if ( k < minCellDim() || k > maxCellDim() ) return R;
330 for ( auto&& c : myKPoints )
331 if ( dim( c ) == k ) R.push_back( c );
335 //-----------------------------------------------------------------------------
336 template <typename TKSpace>
337 typename DGtal::CellGeometry<TKSpace>::Integer
338 DGtal::CellGeometry<TKSpace>::
343 for ( Dimension k = 0; k <= maxCellDim(); ++k )
345 if ( pos ) euler += computeNbCells( k );
346 else euler -= computeNbCells( k );
351 //-----------------------------------------------------------------------------
352 template <typename TKSpace>
354 DGtal::CellGeometry<TKSpace>::
359 //-----------------------------------------------------------------------------
360 template <typename TKSpace>
362 DGtal::CellGeometry<TKSpace>::
368 //-----------------------------------------------------------------------------
369 template <typename TKSpace>
371 DGtal::CellGeometry<TKSpace>::
372 subset( const CellGeometry& other ) const
374 return other.myKPoints.includes( myKPoints );
376 //-----------------------------------------------------------------------------
377 template <typename TKSpace>
379 DGtal::CellGeometry<TKSpace>::
380 subset( const CellGeometry& other, const Dimension k ) const
382 UnorderedSetByBlock< Point, Splitter< Point, uint64_t > > k_dim_points;
383 for ( auto&& c : myKPoints )
385 k_dim_points.insert( c );
386 return other.myKPoints.includes( k_dim_points );
389 //-----------------------------------------------------------------------------
390 template <typename TKSpace>
391 template <typename RandomIterator>
393 DGtal::CellGeometry<TKSpace>::
394 includes( RandomIterator it1, RandomIterator itE1,
395 RandomIterator it2, RandomIterator itE2 )
398 for ( ; it2 != itE2; ++it1)
400 if (it1 == itE1 || *it2 < *it1) return false;
402 for ( k = 1; ( it1 < itE1 ) && ( *it1 < *it2 ); k *= 2 ) it1 += k;
405 if ( *it2 == *it1 ) ++it2; //equality
408 it1 = lower_bound( it1 - k/2, it1, *it2 );
409 if ( *it2 != *it1 ) return false;
415 it1 = lower_bound( it1 - k/2, itE1, *it2 );
416 if ( it1 == itE1 || *it2 != *it1 ) return false;
423 //-----------------------------------------------------------------------------
424 template <typename TKSpace>
425 std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
426 DGtal::CellGeometry<TKSpace>::
427 getIntersectedKPoints( const LatticePolytope& polytope,
428 const Dimension i ) const
430 ASSERT( polytope.canBeSummed() );
431 if ( ! polytope.canBeSummed() )
432 trace.warning() << "[CellGeometryFunctions::getIntersectedKPoints]"
433 << " LatticePolytope is not valid for Minkowski sums. "
435 static const Dimension d = KSpace::dimension;
436 std::vector< Point > result;
437 std::vector< Point > points;
438 std::vector< LatticePolytope > polytopes( i+1, polytope );
439 std::vector< Dimension > extensions( i+1, 0 );
440 for ( Dimension k = 1; k < extensions.size(); ++k )
442 extensions[ k ] = k - 1;
443 polytopes [ k ] = polytopes[ k - 1 ]
444 + typename LatticePolytope::UnitSegment( k - 1 );
446 // We have to build several dilated polytopes which corresponds
447 // to the binom(d,i) possible cell types.
453 std::ostringstream ostr( str );
454 ostr << "Dilating Polytope along directions {";
455 for ( Dimension k = 1; k < extensions.size(); ++k )
456 ostr << " + " << extensions[ k ];
458 trace.info() << ostr.str() << std::endl;
460 // Intersected cells are bijective to points in a dilated polytope.
461 polytopes.back().getPoints( points );
462 // For each point, build its Khalimsky points and push it into result.
463 for ( auto p : points )
465 auto kp = myK.uKCoords( myK.uPointel( p ) );
466 for ( Dimension k = 1; k < extensions.size(); ++k )
467 // decrease Khalimsky coordinate to get incident cell
468 kp[ extensions[ k ] ] -= 1;
469 result.push_back( kp );
471 // Go to next type of cell
473 extensions[ k ] += 1;
474 // will quit when k == 0
475 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
476 if ( k == 0 ) break; // finished
477 for ( Dimension l = k + 1; l < extensions.size(); ++l )
478 extensions[ l ] = extensions[ l - 1 ] + 1;
479 // Recomputes polytopes
480 for ( ; k < extensions.size(); ++k )
481 polytopes [ k ] = polytopes[ k - 1 ]
482 + typename LatticePolytope::UnitSegment( extensions[ k ] );
487 //-----------------------------------------------------------------------------
488 template <typename TKSpace>
489 std::vector< typename DGtal::CellGeometry<TKSpace>::Cell >
490 DGtal::CellGeometry<TKSpace>::
491 getIntersectedCells( const LatticePolytope& polytope,
492 const Dimension i ) const
494 ASSERT( polytope.canBeSummed() );
495 if ( ! polytope.canBeSummed() )
496 trace.warning() << "[CellGeometryFunctions::getIntersectedCells]"
497 << " LatticePolytope is not valid for Minkowski sums. "
499 static const Dimension d = KSpace::dimension;
500 std::vector< Cell > result;
501 std::vector< Point > points;
502 std::vector< LatticePolytope > polytopes( i+1, polytope );
503 std::vector< Dimension > extensions( i+1, 0 );
504 for ( Dimension k = 1; k < extensions.size(); ++k )
506 extensions[ k ] = k - 1;
507 polytopes [ k ] = polytopes[ k - 1 ]
508 + typename LatticePolytope::UnitSegment( k - 1 );
510 // We have to build several dilated polytopes which corresponds
511 // to the binom(d,i) possible cell types.
517 std::ostringstream ostr( str );
518 ostr << "Dilating Polytope along directions {";
519 for ( Dimension k = 1; k < extensions.size(); ++k )
520 ostr << " + " << extensions[ k ];
522 trace.info() << ostr.str() << std::endl;
524 // Intersected cells are bijective to points in a dilated polytope.
525 polytopes.back().getPoints( points );
526 // For each point, build its cell and push it into result.
527 for ( auto p : points )
529 auto cell = myK.uPointel( p );
530 for ( Dimension k = 1; k < extensions.size(); ++k )
531 cell = myK.uIncident( cell, extensions[ k ], false );
532 result.push_back( cell );
534 // Go to next type of cell
536 extensions[ k ] += 1;
537 // will quit when k == 0
538 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
539 if ( k == 0 ) break; // finished
540 for ( Dimension l = k + 1; l < extensions.size(); ++l )
541 extensions[ l ] = extensions[ l - 1 ] + 1;
542 // Recomputes polytopes
543 for ( ; k < extensions.size(); ++k )
544 polytopes [ k ] = polytopes[ k - 1 ]
545 + typename LatticePolytope::UnitSegment( extensions[ k ] );
550 //-----------------------------------------------------------------------------
551 template <typename TKSpace>
552 std::vector< typename DGtal::CellGeometry<TKSpace>::Cell >
553 DGtal::CellGeometry<TKSpace>::
554 getIntersectedCells( const RationalPolytope& polytope,
555 const Dimension i ) const
557 ASSERT( polytope.canBeSummed() );
558 if ( ! polytope.canBeSummed() )
559 trace.warning() << "[CellGeometryFunctions::getIntersectedCells]"
560 << " RationalPolytope is not valid for Minkowski sums. "
562 static const Dimension d = KSpace::dimension;
563 std::vector< Cell > result;
564 std::vector< Point > points;
565 std::vector< RationalPolytope > polytopes( i+1, polytope );
566 std::vector< Dimension > extensions( i+1, 0 );
567 for ( Dimension k = 1; k < extensions.size(); ++k )
569 extensions[ k ] = k - 1;
570 polytopes [ k ] = polytopes[ k - 1 ]
571 + typename RationalPolytope::UnitSegment( k - 1 );
573 // We have to build several dilated polytopes which corresponds
574 // to the binom(d,i) possible cell types.
580 std::ostringstream ostr( str );
581 ostr << "Dilating Polytope along directions {";
582 for ( Dimension k = 1; k < extensions.size(); ++k )
583 ostr << " + " << extensions[ k ];
585 trace.info() << ostr.str() << std::endl;
587 // Intersected cells are bijective to points in a dilated polytope.
588 polytopes.back().getPoints( points );
589 // For each point, build its cell and push it into result.
590 for ( auto p : points )
592 auto cell = myK.uPointel( p );
593 for ( Dimension k = 1; k < extensions.size(); ++k )
594 cell = myK.uIncident( cell, extensions[ k ], false );
595 result.push_back( cell );
597 // Go to next type of cell
599 extensions[ k ] += 1;
600 // will quit when k == 0
601 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
602 if ( k == 0 ) break; // finished
603 for ( Dimension l = k + 1; l < extensions.size(); ++l )
604 extensions[ l ] = extensions[ l - 1 ] + 1;
605 // Recomputes polytopes
606 for ( ; k < extensions.size(); ++k )
607 polytopes [ k ] = polytopes[ k - 1 ]
608 + typename RationalPolytope::UnitSegment( extensions[ k ] );
613 //-----------------------------------------------------------------------------
614 template <typename TKSpace>
615 std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
616 DGtal::CellGeometry<TKSpace>::
617 getIntersectedKPoints( const RationalPolytope& polytope,
618 const Dimension i ) const
620 ASSERT( polytope.canBeSummed() );
621 if ( ! polytope.canBeSummed() )
622 trace.warning() << "[CellGeometryFunctions::getIntersectedKPoints]"
623 << " RationalPolytope is not valid for Minkowski sums. "
625 static const Dimension d = KSpace::dimension;
626 std::vector< Point > result;
627 std::vector< Point > points;
628 std::vector< RationalPolytope > polytopes( i+1, polytope );
629 std::vector< Dimension > extensions( i+1, 0 );
630 for ( Dimension k = 1; k < extensions.size(); ++k )
632 extensions[ k ] = k - 1;
633 polytopes [ k ] = polytopes[ k - 1 ]
634 + typename RationalPolytope::UnitSegment( k - 1 );
636 // We have to build several dilated polytopes which corresponds
637 // to the binom(d,i) possible cell types.
643 std::ostringstream ostr( str );
644 ostr << "Dilating Polytope along directions {";
645 for ( Dimension k = 1; k < extensions.size(); ++k )
646 ostr << " + " << extensions[ k ];
648 trace.info() << ostr.str() << std::endl;
650 // Intersected cells are bijective to points in a dilated polytope.
651 polytopes.back().getPoints( points );
652 // For each point, build its Khalimsky points and push it into result.
653 for ( auto p : points )
655 auto kp = myK.uKCoords( myK.uPointel( p ) );
656 for ( Dimension k = 1; k < extensions.size(); ++k )
657 // decrease Khalimsky coordinate to get incident cell
658 kp[ extensions[ k ] ] -= 1;
659 result.push_back( kp );
661 // Go to next type of cell
663 extensions[ k ] += 1;
664 // will quit when k == 0
665 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
666 if ( k == 0 ) break; // finished
667 for ( Dimension l = k + 1; l < extensions.size(); ++l )
668 extensions[ l ] = extensions[ l - 1 ] + 1;
669 // Recomputes polytopes
670 for ( ; k < extensions.size(); ++k )
671 polytopes [ k ] = polytopes[ k - 1 ]
672 + typename RationalPolytope::UnitSegment( extensions[ k ] );
677 //-----------------------------------------------------------------------------
678 template <typename TKSpace>
679 std::vector< typename DGtal::CellGeometry<TKSpace>::Cell >
680 DGtal::CellGeometry<TKSpace>::
681 getTouchedCells( const std::vector< Point >& points, const Dimension i ) const
683 std::unordered_set< Cell > cells;
685 cells = CellGeometryFunctions< KSpace, 0, KSpace::dimension>
686 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
688 cells = CellGeometryFunctions< KSpace, 1, KSpace::dimension>
689 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
691 cells = CellGeometryFunctions< KSpace, 2, KSpace::dimension>
692 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
694 cells = CellGeometryFunctions< KSpace, 3, KSpace::dimension>
695 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
697 cells = CellGeometryFunctions< KSpace, 4, KSpace::dimension>
698 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
700 cells = CellGeometryFunctions< KSpace, 5, KSpace::dimension>
701 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
702 else trace.error() << "[DGtal::CellGeometry<TKSpace>::getTouchedCells]"
703 << " Computation are limited to n-D, n <= 5" << std::endl;
704 return std::vector< Cell >( cells.begin(), cells.end() );
707 //-----------------------------------------------------------------------------
708 template <typename TKSpace>
709 std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
710 DGtal::CellGeometry<TKSpace>::
711 getTouchedKPoints( const std::vector< Point >& points, const Dimension i ) const
713 UnorderedSetByBlock< Point, Splitter< Point, uint64_t > > kpoints;
715 kpoints = CellGeometryFunctions< KSpace, 0, KSpace::dimension>
716 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
718 kpoints = CellGeometryFunctions< KSpace, 1, KSpace::dimension>
719 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
721 kpoints = CellGeometryFunctions< KSpace, 2, KSpace::dimension>
722 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
724 kpoints = CellGeometryFunctions< KSpace, 3, KSpace::dimension>
725 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
727 kpoints = CellGeometryFunctions< KSpace, 4, KSpace::dimension>
728 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
730 kpoints = CellGeometryFunctions< KSpace, 5, KSpace::dimension>
731 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
732 else trace.error() << "[DGtal::CellGeometry<TKSpace>::getTouchedKPoints]"
733 << " Computation are limited to n-D, n <= 5" << std::endl;
734 return std::vector< Cell >( kpoints.begin(), kpoints.end() );
738 //-----------------------------------------------------------------------------
739 template <typename TKSpace>
741 DGtal::CellGeometry<TKSpace>::
742 dim( const Point & kp )
745 for ( Dimension i = 0; i < KSpace::dimension; ++i )
746 d += kp[ i ] & 1 ? 1 : 0;
750 ///////////////////////////////////////////////////////////////////////////////
751 // Interface - public :
754 * Writes/Displays the object on an output stream.
755 * @param out the output stream where the object is written.
757 template <typename TKSpace>
760 DGtal::CellGeometry<TKSpace>::selfDisplay ( std::ostream & out ) const
762 out << "[CellGeometry] ";
763 std::vector< Point > X;
764 for ( auto && c : myKPoints ) X.push_back( c );
765 std::sort( X.begin(), X.end() );
768 out << "(" << p[ 0 ];
769 for ( Dimension k = 1; k < TKSpace::dimension; ++k )
770 out << "," << p[ k ];
776 * Checks the validity/consistency of the object.
777 * @return 'true' if the object is valid, 'false' otherwise.
779 template <typename TKSpace>
782 DGtal::CellGeometry<TKSpace>::isValid() const
786 //-----------------------------------------------------------------------------
787 template <typename TKSpace>
790 DGtal::CellGeometry<TKSpace>::className
793 return "CellGeometry";
798 ///////////////////////////////////////////////////////////////////////////////
799 // Implementation of inline functions //
801 //-----------------------------------------------------------------------------
802 template <typename TKSpace>
805 DGtal::operator<< ( std::ostream & out,
806 const CellGeometry<TKSpace> & object )
808 object.selfDisplay( out );
813 ///////////////////////////////////////////////////////////////////////////////