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//-----------------------------------------------------------------------------
45template <typename TKSpace>
46DGtal::CellGeometry<TKSpace>::
49 myMinCellDim( 0 ), myMaxCellDim( KSpace::dimension ),
54//-----------------------------------------------------------------------------
55template <typename TKSpace>
56DGtal::CellGeometry<TKSpace>::
57CellGeometry( 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( 0 <= myMinCellDim );
64 ASSERT( myMinCellDim <= myMaxCellDim );
65 ASSERT( myMaxCellDim <= myK.dimension );
67//-----------------------------------------------------------------------------
68template <typename TKSpace>
70DGtal::CellGeometry<TKSpace>::
71init( const KSpace & K,
72 Dimension min_cell_dim, Dimension max_cell_dim, bool verbose )
74 ASSERT( 0 <= myMinCellDim );
75 ASSERT( myMinCellDim <= myMaxCellDim );
76 ASSERT( myMaxCellDim <= myK.dimension );
79 myMinCellDim = min_cell_dim;
80 myMaxCellDim = max_cell_dim;
84//-----------------------------------------------------------------------------
85template <typename TKSpace>
87DGtal::CellGeometry<TKSpace>::
88addCellsTouchingPoint( const Point& p )
90 addCellsTouchingPointel( myK.uPointel( p ) );
93//-----------------------------------------------------------------------------
94template <typename TKSpace>
96DGtal::CellGeometry<TKSpace>::
97addCellsTouchingPointel( const Cell& pointel )
99 auto cofaces = myK.uCoFaces( pointel );
100 if ( ( myMinCellDim == 0 ) && ( myMaxCellDim == KSpace::dimension ) )
102 myKPoints.emplace( myK.uKCoords( pointel ) );
103 for ( auto && c : cofaces )
104 myKPoints.emplace( myK.uKCoords( c ) );
108 if ( myMinCellDim <= 0 )
109 myKPoints.emplace( myK.uKCoords( pointel ) );
110 for ( auto&& f : cofaces )
112 Dimension d = myK.uDim( f );
113 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
114 myKPoints.emplace( myK.uKCoords( f ) );
119//-----------------------------------------------------------------------------
120template <typename TKSpace>
122DGtal::CellGeometry<TKSpace>::
123addCellsTouchingCell( const Cell& c )
125 const Dimension dc = myK.uDim( c );
126 if ( myMinCellDim <= dc && dc <= myMaxCellDim )
127 myKPoints.emplace( myK.uKCoords( c ) );
128 if ( myMaxCellDim <= dc ) return;
129 const auto cofaces = myK.uCoFaces( c );
130 for ( auto&& f : cofaces )
132 Dimension d = myK.uDim( f );
133 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
134 myKPoints.emplace( myK.uKCoords( f ) );
138//-----------------------------------------------------------------------------
139template <typename TKSpace>
141DGtal::CellGeometry<TKSpace>::
142addCellsTouchingSegment( const Point& a, const Point& b )
144 const auto V = b - a;
145 addCellsTouchingPoint( a );
146 for ( Integer k = 0; k < dimension; k++ )
148 const Integer n = ( V[ k ] >= 0 ) ? V[ k ] : -V[ k ];
149 const Integer d = ( V[ k ] >= 0 ) ? 1 : -1;
150 if ( n == 0 ) continue;
152 for ( Integer i = 1; i < n; i++ )
154 for ( Dimension j = 0; j < dimension; j++ )
156 if ( j == k ) kc[ k ] = 2 * ( a[ k ] + d * i );
159 const auto v = V[ j ];
160 const auto q = ( v * i ) / n;
161 const auto r = ( v * i ) % n; // might be negative
162 kc[ j ] = 2 * ( a[ j ] + q );
163 if ( r < 0 ) kc[ j ] -= 1;
164 else if ( r > 0 ) kc[ j ] += 1;
167 addCellsTouchingCell( myK.uCell( kc ) );
170 if ( a != b ) addCellsTouchingPoint( b );
173//-----------------------------------------------------------------------------
174template <typename TKSpace>
175template <typename PointIterator>
177DGtal::CellGeometry<TKSpace>::
178addCellsTouchingPoints( PointIterator itB, PointIterator itE )
180 if ( ( myMinCellDim == 0 ) && ( myMaxCellDim == KSpace::dimension ) )
182 for ( auto it = itB; it != itE; ++it )
184 auto pointel = myK.uPointel( *it );
185 auto cofaces = myK.uCoFaces( pointel );
186 myKPoints.emplace( myK.uKCoords( pointel ) );
187 for ( auto && c : cofaces )
188 myKPoints.emplace( myK.uKCoords( c ) );
193 for ( auto it = itB; it != itE; ++it )
195 auto pointel = myK.uPointel( *it );
196 auto cofaces = myK.uCoFaces( pointel );
197 if ( myMinCellDim <= 0 )
198 myKPoints.emplace( myK.uKCoords( pointel ) );
199 for ( auto&& f : cofaces )
201 Dimension d = myK.uDim( f );
202 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
203 myKPoints.emplace( myK.uKCoords( f ) );
209//-----------------------------------------------------------------------------
210template <typename TKSpace>
211template <typename PointelIterator>
213DGtal::CellGeometry<TKSpace>::
214addCellsTouchingPointels( PointelIterator itB, PointelIterator itE )
216 if ( ( myMinCellDim == 0 ) && ( myMaxCellDim == KSpace::dimension ) )
218 for ( auto it = itB; it != itE; ++it )
221 auto cofaces = myK.uCoFaces( pointel );
222 myKPoints.emplace( myK.uKCoords( pointel ) );
223 for ( auto && c : cofaces )
224 myKPoints.emplace( myK.uKCoords( c ) );
229 for ( auto it = itB; it != itE; ++it )
232 auto cofaces = myK.uCoFaces( pointel );
233 if ( myMinCellDim <= 0 )
234 myKPoints.emplace( myK.uKCoords( pointel ) );
235 for ( auto&& f : cofaces )
237 Dimension d = myK.uDim( f );
238 if ( ( myMinCellDim <= d ) && ( d <= myMaxCellDim ) )
239 myKPoints.emplace( myK.uKCoords( f ) );
244//-----------------------------------------------------------------------------
245template <typename TKSpace>
247DGtal::CellGeometry<TKSpace>::
248addCellsTouchingPolytopePoints( const LatticePolytope& polytope )
250 std::vector< Point > points;
251 polytope.getPoints( points );
252 addCellsTouchingPoints( points.begin(), points.end() );
254//-----------------------------------------------------------------------------
255template <typename TKSpace>
257DGtal::CellGeometry<TKSpace>::
258addCellsTouchingPolytopePoints( const RationalPolytope& polytope )
260 std::vector< Point > points;
261 polytope.getPoints( points );
262 addCellsTouchingPoints( points.cbegin(), points.cend() );
264//-----------------------------------------------------------------------------
265template <typename TKSpace>
267DGtal::CellGeometry<TKSpace>::
268addCellsTouchingPolytope( const LatticePolytope& polytope )
270 for ( Dimension i = myMinCellDim; i <= myMaxCellDim; ++i )
272 auto kpoints = getIntersectedKPoints( polytope, i );
273 myKPoints.insert( kpoints.cbegin(), kpoints.cend() );
276//-----------------------------------------------------------------------------
277template <typename TKSpace>
279DGtal::CellGeometry<TKSpace>::
280addCellsTouchingPolytope( const RationalPolytope& polytope )
282 for ( Dimension i = myMinCellDim; i <= myMaxCellDim; ++i )
284 auto kpoints = getIntersectedKPoints( polytope, i );
285 myKPoints.insert( kpoints.cbegin(), kpoints.cend() );
288//-----------------------------------------------------------------------------
289template <typename TKSpace>
290typename DGtal::CellGeometry<TKSpace>&
291DGtal::CellGeometry<TKSpace>::
292operator+=( const CellGeometry& other )
294 if ( this != &other )
296 myKPoints.insert( other.myKPoints.cbegin(), other.myKPoints.cend() );
297 myMinCellDim = std::min( myMinCellDim, other.myMinCellDim );
298 myMaxCellDim = std::max( myMaxCellDim, other.myMaxCellDim );
303//-----------------------------------------------------------------------------
304template <typename TKSpace>
305typename DGtal::CellGeometry<TKSpace>::Size
306DGtal::CellGeometry<TKSpace>::
309 return myKPoints.size();
311//-----------------------------------------------------------------------------
312template <typename TKSpace>
313typename DGtal::CellGeometry<TKSpace>::Size
314DGtal::CellGeometry<TKSpace>::
315computeNbCells( const Dimension k ) const
317 if ( k < minCellDim() || k > maxCellDim() ) return 0;
319 for ( auto&& c : myKPoints )
320 nb += ( dim( c ) == k ) ? 1 : 0;
324//-----------------------------------------------------------------------------
325template <typename TKSpace>
326std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
327DGtal::CellGeometry<TKSpace>::
328getKPoints( const Dimension k ) const
330 std::vector< Point > R;
331 if ( k < minCellDim() || k > maxCellDim() ) return R;
332 for ( auto&& c : myKPoints )
333 if ( dim( c ) == k ) R.push_back( c );
337//-----------------------------------------------------------------------------
338template <typename TKSpace>
339typename DGtal::CellGeometry<TKSpace>::Integer
340DGtal::CellGeometry<TKSpace>::
345 for ( Dimension k = 0; k <= maxCellDim(); ++k )
347 if ( pos ) euler += computeNbCells( k );
348 else euler -= computeNbCells( k );
353//-----------------------------------------------------------------------------
354template <typename TKSpace>
356DGtal::CellGeometry<TKSpace>::
361//-----------------------------------------------------------------------------
362template <typename TKSpace>
364DGtal::CellGeometry<TKSpace>::
370//-----------------------------------------------------------------------------
371template <typename TKSpace>
373DGtal::CellGeometry<TKSpace>::
374subset( const CellGeometry& other ) const
376 return other.myKPoints.includes( myKPoints );
378//-----------------------------------------------------------------------------
379template <typename TKSpace>
381DGtal::CellGeometry<TKSpace>::
382subset( const CellGeometry& other, const Dimension k ) const
384 UnorderedSetByBlock< Point, Splitter< Point, uint64_t > > k_dim_points;
385 for ( auto&& c : myKPoints )
387 k_dim_points.insert( c );
388 return other.myKPoints.includes( k_dim_points );
391//-----------------------------------------------------------------------------
392template <typename TKSpace>
393template <typename RandomIterator>
395DGtal::CellGeometry<TKSpace>::
396includes( RandomIterator it1, RandomIterator itE1,
397 RandomIterator it2, RandomIterator itE2 )
400 for ( ; it2 != itE2; ++it1)
402 if (it1 == itE1 || *it2 < *it1) return false;
404 for ( k = 1; ( it1 < itE1 ) && ( *it1 < *it2 ); k *= 2 ) it1 += k;
407 if ( *it2 == *it1 ) ++it2; //equality
410 it1 = lower_bound( it1 - k/2, it1, *it2 );
411 if ( *it2 != *it1 ) return false;
417 it1 = lower_bound( it1 - k/2, itE1, *it2 );
418 if ( it1 == itE1 || *it2 != *it1 ) return false;
425//-----------------------------------------------------------------------------
426template <typename TKSpace>
427std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
428DGtal::CellGeometry<TKSpace>::
429getIntersectedKPoints( const LatticePolytope& polytope,
430 const Dimension i ) const
432 ASSERT( polytope.canBeSummed() );
433 if ( ! polytope.canBeSummed() )
434 trace.warning() << "[CellGeometryFunctions::getIntersectedKPoints]"
435 << " LatticePolytope is not valid for Minkowski sums. "
437 static const Dimension d = KSpace::dimension;
438 std::vector< Point > result;
439 std::vector< Point > points;
440 std::vector< LatticePolytope > polytopes( i+1, polytope );
441 std::vector< Dimension > extensions( i+1, 0 );
442 for ( Dimension k = 1; k < extensions.size(); ++k )
444 extensions[ k ] = k - 1;
445 polytopes [ k ] = polytopes[ k - 1 ]
446 + typename LatticePolytope::UnitSegment( k - 1 );
448 // We have to build several dilated polytopes which corresponds
449 // to the binom(d,i) possible cell types.
455 std::ostringstream ostr( str );
456 ostr << "Dilating Polytope along directions {";
457 for ( Dimension k = 1; k < extensions.size(); ++k )
458 ostr << " + " << extensions[ k ];
460 trace.info() << ostr.str() << std::endl;
462 // Intersected cells are bijective to points in a dilated polytope.
463 polytopes.back().getPoints( points );
464 // For each point, build its Khalimsky points and push it into result.
465 for ( auto p : points )
467 auto kp = myK.uKCoords( myK.uPointel( p ) );
468 for ( Dimension k = 1; k < extensions.size(); ++k )
469 // decrease Khalimsky coordinate to get incident cell
470 kp[ extensions[ k ] ] -= 1;
471 result.push_back( kp );
473 // Go to next type of cell
475 extensions[ k ] += 1;
476 // will quit when k == 0
477 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
478 if ( k == 0 ) break; // finished
479 for ( Dimension l = k + 1; l < extensions.size(); ++l )
480 extensions[ l ] = extensions[ l - 1 ] + 1;
481 // Recomputes polytopes
482 for ( ; k < extensions.size(); ++k )
483 polytopes [ k ] = polytopes[ k - 1 ]
484 + typename LatticePolytope::UnitSegment( extensions[ k ] );
489//-----------------------------------------------------------------------------
490template <typename TKSpace>
491std::vector< typename DGtal::CellGeometry<TKSpace>::Cell >
492DGtal::CellGeometry<TKSpace>::
493getIntersectedCells( const LatticePolytope& polytope,
494 const Dimension i ) const
496 ASSERT( polytope.canBeSummed() );
497 if ( ! polytope.canBeSummed() )
498 trace.warning() << "[CellGeometryFunctions::getIntersectedCells]"
499 << " LatticePolytope is not valid for Minkowski sums. "
501 static const Dimension d = KSpace::dimension;
502 std::vector< Cell > result;
503 std::vector< Point > points;
504 std::vector< LatticePolytope > polytopes( i+1, polytope );
505 std::vector< Dimension > extensions( i+1, 0 );
506 for ( Dimension k = 1; k < extensions.size(); ++k )
508 extensions[ k ] = k - 1;
509 polytopes [ k ] = polytopes[ k - 1 ]
510 + typename LatticePolytope::UnitSegment( k - 1 );
512 // We have to build several dilated polytopes which corresponds
513 // to the binom(d,i) possible cell types.
519 std::ostringstream ostr( str );
520 ostr << "Dilating Polytope along directions {";
521 for ( Dimension k = 1; k < extensions.size(); ++k )
522 ostr << " + " << extensions[ k ];
524 trace.info() << ostr.str() << std::endl;
526 // Intersected cells are bijective to points in a dilated polytope.
527 polytopes.back().getPoints( points );
528 // For each point, build its cell and push it into result.
529 for ( auto p : points )
531 auto cell = myK.uPointel( p );
532 for ( Dimension k = 1; k < extensions.size(); ++k )
533 cell = myK.uIncident( cell, extensions[ k ], false );
534 result.push_back( cell );
536 // Go to next type of cell
538 extensions[ k ] += 1;
539 // will quit when k == 0
540 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
541 if ( k == 0 ) break; // finished
542 for ( Dimension l = k + 1; l < extensions.size(); ++l )
543 extensions[ l ] = extensions[ l - 1 ] + 1;
544 // Recomputes polytopes
545 for ( ; k < extensions.size(); ++k )
546 polytopes [ k ] = polytopes[ k - 1 ]
547 + typename LatticePolytope::UnitSegment( extensions[ k ] );
552//-----------------------------------------------------------------------------
553template <typename TKSpace>
554std::vector< typename DGtal::CellGeometry<TKSpace>::Cell >
555DGtal::CellGeometry<TKSpace>::
556getIntersectedCells( const RationalPolytope& polytope,
557 const Dimension i ) const
559 ASSERT( polytope.canBeSummed() );
560 if ( ! polytope.canBeSummed() )
561 trace.warning() << "[CellGeometryFunctions::getIntersectedCells]"
562 << " RationalPolytope is not valid for Minkowski sums. "
564 static const Dimension d = KSpace::dimension;
565 std::vector< Cell > result;
566 std::vector< Point > points;
567 std::vector< RationalPolytope > polytopes( i+1, polytope );
568 std::vector< Dimension > extensions( i+1, 0 );
569 for ( Dimension k = 1; k < extensions.size(); ++k )
571 extensions[ k ] = k - 1;
572 polytopes [ k ] = polytopes[ k - 1 ]
573 + typename RationalPolytope::UnitSegment( k - 1 );
575 // We have to build several dilated polytopes which corresponds
576 // to the binom(d,i) possible cell types.
582 std::ostringstream ostr( str );
583 ostr << "Dilating Polytope along directions {";
584 for ( Dimension k = 1; k < extensions.size(); ++k )
585 ostr << " + " << extensions[ k ];
587 trace.info() << ostr.str() << std::endl;
589 // Intersected cells are bijective to points in a dilated polytope.
590 polytopes.back().getPoints( points );
591 // For each point, build its cell and push it into result.
592 for ( auto p : points )
594 auto cell = myK.uPointel( p );
595 for ( Dimension k = 1; k < extensions.size(); ++k )
596 cell = myK.uIncident( cell, extensions[ k ], false );
597 result.push_back( cell );
599 // Go to next type of cell
601 extensions[ k ] += 1;
602 // will quit when k == 0
603 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
604 if ( k == 0 ) break; // finished
605 for ( Dimension l = k + 1; l < extensions.size(); ++l )
606 extensions[ l ] = extensions[ l - 1 ] + 1;
607 // Recomputes polytopes
608 for ( ; k < extensions.size(); ++k )
609 polytopes [ k ] = polytopes[ k - 1 ]
610 + typename RationalPolytope::UnitSegment( extensions[ k ] );
615//-----------------------------------------------------------------------------
616template <typename TKSpace>
617std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
618DGtal::CellGeometry<TKSpace>::
619getIntersectedKPoints( const RationalPolytope& polytope,
620 const Dimension i ) const
622 ASSERT( polytope.canBeSummed() );
623 if ( ! polytope.canBeSummed() )
624 trace.warning() << "[CellGeometryFunctions::getIntersectedKPoints]"
625 << " RationalPolytope is not valid for Minkowski sums. "
627 static const Dimension d = KSpace::dimension;
628 std::vector< Point > result;
629 std::vector< Point > points;
630 std::vector< RationalPolytope > polytopes( i+1, polytope );
631 std::vector< Dimension > extensions( i+1, 0 );
632 for ( Dimension k = 1; k < extensions.size(); ++k )
634 extensions[ k ] = k - 1;
635 polytopes [ k ] = polytopes[ k - 1 ]
636 + typename RationalPolytope::UnitSegment( k - 1 );
638 // We have to build several dilated polytopes which corresponds
639 // to the binom(d,i) possible cell types.
645 std::ostringstream ostr( str );
646 ostr << "Dilating Polytope along directions {";
647 for ( Dimension k = 1; k < extensions.size(); ++k )
648 ostr << " + " << extensions[ k ];
650 trace.info() << ostr.str() << std::endl;
652 // Intersected cells are bijective to points in a dilated polytope.
653 polytopes.back().getPoints( points );
654 // For each point, build its Khalimsky points and push it into result.
655 for ( auto p : points )
657 auto kp = myK.uKCoords( myK.uPointel( p ) );
658 for ( Dimension k = 1; k < extensions.size(); ++k )
659 // decrease Khalimsky coordinate to get incident cell
660 kp[ extensions[ k ] ] -= 1;
661 result.push_back( kp );
663 // Go to next type of cell
665 extensions[ k ] += 1;
666 // will quit when k == 0
667 while ( k > 0 && extensions[ k ] >= d+k-i ) extensions[ --k ] += 1;
668 if ( k == 0 ) break; // finished
669 for ( Dimension l = k + 1; l < extensions.size(); ++l )
670 extensions[ l ] = extensions[ l - 1 ] + 1;
671 // Recomputes polytopes
672 for ( ; k < extensions.size(); ++k )
673 polytopes [ k ] = polytopes[ k - 1 ]
674 + typename RationalPolytope::UnitSegment( extensions[ k ] );
679//-----------------------------------------------------------------------------
680template <typename TKSpace>
681std::vector< typename DGtal::CellGeometry<TKSpace>::Cell >
682DGtal::CellGeometry<TKSpace>::
683getTouchedCells( const std::vector< Point >& points, const Dimension i ) const
685 std::unordered_set< Cell > cells;
687 cells = CellGeometryFunctions< KSpace, 0, KSpace::dimension>
688 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
690 cells = CellGeometryFunctions< KSpace, 1, KSpace::dimension>
691 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
693 cells = CellGeometryFunctions< KSpace, 2, KSpace::dimension>
694 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
696 cells = CellGeometryFunctions< KSpace, 3, KSpace::dimension>
697 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
699 cells = CellGeometryFunctions< KSpace, 4, KSpace::dimension>
700 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
702 cells = CellGeometryFunctions< KSpace, 5, KSpace::dimension>
703 ::getIncidentCellsToPoints( myK, points.begin(), points.end() );
704 else trace.error() << "[DGtal::CellGeometry<TKSpace>::getTouchedCells]"
705 << " Computation are limited to n-D, n <= 5" << std::endl;
706 return std::vector< Cell >( cells.begin(), cells.end() );
709//-----------------------------------------------------------------------------
710template <typename TKSpace>
711std::vector< typename DGtal::CellGeometry<TKSpace>::Point >
712DGtal::CellGeometry<TKSpace>::
713getTouchedKPoints( const std::vector< Point >& points, const Dimension i ) const
715 UnorderedSetByBlock< Point, Splitter< Point, uint64_t > > kpoints;
717 kpoints = CellGeometryFunctions< KSpace, 0, KSpace::dimension>
718 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
720 kpoints = CellGeometryFunctions< KSpace, 1, KSpace::dimension>
721 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
723 kpoints = CellGeometryFunctions< KSpace, 2, KSpace::dimension>
724 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
726 kpoints = CellGeometryFunctions< KSpace, 3, KSpace::dimension>
727 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
729 kpoints = CellGeometryFunctions< KSpace, 4, KSpace::dimension>
730 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
732 kpoints = CellGeometryFunctions< KSpace, 5, KSpace::dimension>
733 ::getIncidentKPointsToPoints( myK, points.begin(), points.end() );
734 else trace.error() << "[DGtal::CellGeometry<TKSpace>::getTouchedKPoints]"
735 << " Computation are limited to n-D, n <= 5" << std::endl;
736 return std::vector< Cell >( kpoints.begin(), kpoints.end() );
740//-----------------------------------------------------------------------------
741template <typename TKSpace>
743DGtal::CellGeometry<TKSpace>::
744dim( const Point & kp )
747 for ( Dimension i = 0; i < KSpace::dimension; ++i )
748 d += kp[ i ] & 1 ? 1 : 0;
752///////////////////////////////////////////////////////////////////////////////
753// Interface - public :
756 * Writes/Displays the object on an output stream.
757 * @param out the output stream where the object is written.
759template <typename TKSpace>
762DGtal::CellGeometry<TKSpace>::selfDisplay ( std::ostream & out ) const
764 out << "[CellGeometry] ";
765 std::vector< Point > X;
766 for ( auto && c : myKPoints ) X.push_back( c );
767 std::sort( X.begin(), X.end() );
770 out << "(" << p[ 0 ];
771 for ( Dimension k = 1; k < TKSpace::dimension; ++k )
772 out << "," << p[ k ];
778 * Checks the validity/consistency of the object.
779 * @return 'true' if the object is valid, 'false' otherwise.
781template <typename TKSpace>
784DGtal::CellGeometry<TKSpace>::isValid() const
788//-----------------------------------------------------------------------------
789template <typename TKSpace>
792DGtal::CellGeometry<TKSpace>::className
795 return "CellGeometry";
800///////////////////////////////////////////////////////////////////////////////
801// Implementation of inline functions //
803//-----------------------------------------------------------------------------
804template <typename TKSpace>
807DGtal::operator<< ( std::ostream & out,
808 const CellGeometry<TKSpace> & object )
810 object.selfDisplay( out );
815///////////////////////////////////////////////////////////////////////////////