31#if defined(CellGeometry_RECURSES)
32#error Recursive header files inclusion detected in CellGeometry.h
35#define CellGeometry_RECURSES
37#if !defined CellGeometry_h
47#include <unordered_set>
48#include "DGtal/base/Common.h"
49#include "DGtal/kernel/UnorderedSetByBlock.h"
50#include "DGtal/kernel/PointHashFunctions.h"
51#include "DGtal/topology/CCellularGridSpaceND.h"
52#include "DGtal/topology/KhalimskySpaceND.h"
53#include "DGtal/topology/KhalimskyCellHashFunctions.h"
54#include "DGtal/geometry/volumes/BoundedLatticePolytope.h"
55#include "DGtal/geometry/volumes/BoundedRationalPolytope.h"
73 template <
typename TKSpace >
130 bool verbose =
false );
149 bool verbose =
false );
184 template <
typename Po
intIterator>
189 template <
typename Po
intelIterator>
398 template <
typename RandomIterator>
400 bool includes( RandomIterator it2, RandomIterator itE2,
401 RandomIterator it1, RandomIterator itE1 );
414 template <
typename TKSpace>
428 template <
typename TKSpace,
int i,
int N>
443 template <
typename Po
intelIterator>
445 std::unordered_set<typename KSpace::Cell>
447 PointelIterator itB, PointelIterator itE )
449 std::unordered_set<typename KSpace::Cell> cells;
451 for (
auto it = itB; it != itE; ++it )
454 for (
auto it = itB; it != itE; ++it )
457 auto cofaces =
K.uCoFaces( pointel );
458 for (
auto&& f : cofaces )
459 if (
K.uDim( f ) == i ) cells.insert( f );
470 template <
typename Po
intIterator>
472 std::unordered_set<typename KSpace::Cell>
474 PointIterator itB, PointIterator itE )
476 std::unordered_set<typename KSpace::Cell> cells;
478 for (
auto it = itB; it != itE; ++it )
479 cells.insert(
K.uPointel( *it ) );
481 for (
auto it = itB; it != itE; ++it )
483 auto pointel =
K.uPointel( *it );
484 auto cofaces =
K.uCoFaces( pointel );
485 for (
auto&& f : cofaces )
486 if (
K.uDim( f ) == i ) cells.insert( f );
497 template <
typename Po
intIterator>
502 PointIterator itB, PointIterator itE )
507 for (
auto it = itB; it != itE; ++it )
508 kpoints.insert(
K.uKCoords(
K.uPointel( *it ) ) );
510 for (
auto it = itB; it != itE; ++it )
512 auto pointel =
K.uPointel( *it );
513 auto cofaces =
K.uCoFaces( pointel );
514 for (
auto&& f : cofaces )
515 if (
K.uDim( f ) == i ) kpoints.insert(
K.uKCoords( f ) );
525 template <
typename TKSpace>
539 template <
typename Po
intelIterator>
541 std::unordered_set<typename KSpace::Cell>
543 PointelIterator itB, PointelIterator itE )
545 std::unordered_set<typename KSpace::Cell> cells;
546 for (
auto it = itB; it != itE; ++it )
549 cells.insert(
K.uIncident( pointel, 0,
true ) );
550 cells.insert(
K.uIncident( pointel, 0,
false ) );
551 cells.insert(
K.uIncident( pointel, 1,
true ) );
552 cells.insert(
K.uIncident( pointel, 1,
false ) );
562 template <
typename Po
intIterator>
564 std::unordered_set<typename KSpace::Cell>
566 PointIterator itB, PointIterator itE )
568 std::unordered_set<typename KSpace::Cell> cells;
569 for (
auto it = itB; it != itE; ++it )
571 auto pointel =
K.uPointel( *it );
572 cells.insert(
K.uIncident( pointel, 0,
true ) );
573 cells.insert(
K.uIncident( pointel, 0,
false ) );
574 cells.insert(
K.uIncident( pointel, 1,
true ) );
575 cells.insert(
K.uIncident( pointel, 1,
false ) );
585 template <
typename Po
intIterator>
590 PointIterator itB, PointIterator itE )
594 for (
auto it = itB; it != itE; ++it )
596 auto kp =
K.uKCoords(
K.uPointel( *it ) );
597 kpoints.emplace( kp[ 0 ] , kp[ 1 ] - 1 );
598 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] );
599 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] );
600 kpoints.emplace( kp[ 0 ] , kp[ 1 ] + 1 );
609 template <
typename TKSpace>
623 template <
typename Po
intelIterator>
625 std::unordered_set<typename KSpace::Cell>
627 PointelIterator itB, PointelIterator itE )
629 std::unordered_set<typename KSpace::Cell> cells;
630 for (
auto it = itB; it != itE; ++it )
633 cells.insert(
K.uIncident( pointel, 0,
true ) );
634 cells.insert(
K.uIncident( pointel, 0,
false ) );
635 cells.insert(
K.uIncident( pointel, 1,
true ) );
636 cells.insert(
K.uIncident( pointel, 1,
false ) );
637 cells.insert(
K.uIncident( pointel, 2,
true ) );
638 cells.insert(
K.uIncident( pointel, 2,
false ) );
649 template <
typename Po
intIterator>
651 std::unordered_set<typename KSpace::Cell>
653 PointIterator itB, PointIterator itE )
655 std::cout <<
"<1,3> specialization" << std::endl;
656 std::unordered_set<typename KSpace::Cell> cells;
657 for (
auto it = itB; it != itE; ++it )
659 auto pointel =
K.uPointel( *it );
660 cells.insert(
K.uIncident( pointel, 0,
true ) );
661 cells.insert(
K.uIncident( pointel, 0,
false ) );
662 cells.insert(
K.uIncident( pointel, 1,
true ) );
663 cells.insert(
K.uIncident( pointel, 1,
false ) );
664 cells.insert(
K.uIncident( pointel, 2,
true ) );
665 cells.insert(
K.uIncident( pointel, 2,
false ) );
675 template <
typename Po
intIterator>
680 PointIterator itB, PointIterator itE )
684 for (
auto it = itB; it != itE; ++it )
686 auto kp =
K.uKCoords(
K.uPointel( *it ) );
687 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] , kp[ 2 ] );
688 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] , kp[ 2 ] );
689 kpoints.emplace( kp[ 0 ] , kp[ 1 ] - 1, kp[ 2 ] );
690 kpoints.emplace( kp[ 0 ] , kp[ 1 ] + 1, kp[ 2 ] );
691 kpoints.emplace( kp[ 0 ] , kp[ 1 ] , kp[ 2 ] - 1 );
692 kpoints.emplace( kp[ 0 ] , kp[ 1 ] , kp[ 2 ] + 1 );
701 template <
typename TKSpace>
715 template <
typename Po
intelIterator>
717 std::unordered_set<typename KSpace::Cell>
719 PointelIterator itB, PointelIterator itE )
721 std::unordered_set<typename KSpace::Cell> cells;
722 for (
auto it = itB; it != itE; ++it )
725 auto linelxp =
K.uIncident( pointel, 0,
true );
726 auto linelxm =
K.uIncident( pointel, 0,
false );
727 cells.insert(
K.uIncident( linelxp, 1,
true ) );
728 cells.insert(
K.uIncident( linelxp, 1,
false ) );
729 cells.insert(
K.uIncident( linelxm, 1,
true ) );
730 cells.insert(
K.uIncident( linelxm, 1,
false ) );
741 template <
typename Po
intIterator>
743 std::unordered_set<typename KSpace::Cell>
745 PointIterator itB, PointIterator itE )
747 std::cout <<
"<2,2> specialization" << std::endl;
748 std::unordered_set<typename KSpace::Cell> cells;
749 for (
auto it = itB; it != itE; ++it )
751 auto pointel =
K.uPointel( *it );
752 auto linelxp =
K.uIncident( pointel, 0,
true );
753 auto linelxm =
K.uIncident( pointel, 0,
false );
754 cells.insert(
K.uIncident( linelxp, 1,
true ) );
755 cells.insert(
K.uIncident( linelxp, 1,
false ) );
756 cells.insert(
K.uIncident( linelxm, 1,
true ) );
757 cells.insert(
K.uIncident( linelxm, 1,
false ) );
767 template <
typename Po
intIterator>
772 PointIterator itB, PointIterator itE )
776 for (
auto it = itB; it != itE; ++it )
778 auto kp =
K.uKCoords(
K.uPointel( *it ) );
779 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] - 1 );
780 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] - 1 );
781 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] + 1 );
782 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] + 1 );
791 template <
typename TKSpace>
805 template <
typename Po
intelIterator>
807 std::unordered_set<typename KSpace::Cell>
809 PointelIterator itB, PointelIterator itE )
811 std::unordered_set<typename KSpace::Cell> cells;
812 for (
auto it = itB; it != itE; ++it )
815 auto linelxp =
K.uIncident( pointel, 0,
true );
816 auto linelxm =
K.uIncident( pointel, 0,
false );
817 auto linelyp =
K.uIncident( pointel, 1,
true );
818 auto linelym =
K.uIncident( pointel, 1,
false );
819 cells.insert(
K.uIncident( linelxp, 1,
true ) );
820 cells.insert(
K.uIncident( linelxp, 1,
false ) );
821 cells.insert(
K.uIncident( linelxp, 2,
true ) );
822 cells.insert(
K.uIncident( linelxp, 2,
false ) );
823 cells.insert(
K.uIncident( linelxm, 1,
true ) );
824 cells.insert(
K.uIncident( linelxm, 1,
false ) );
825 cells.insert(
K.uIncident( linelxm, 2,
true ) );
826 cells.insert(
K.uIncident( linelxm, 2,
false ) );
827 cells.insert(
K.uIncident( linelyp, 2,
true ) );
828 cells.insert(
K.uIncident( linelyp, 2,
false ) );
829 cells.insert(
K.uIncident( linelym, 2,
true ) );
830 cells.insert(
K.uIncident( linelym, 2,
false ) );
841 template <
typename Po
intIterator>
843 std::unordered_set<typename KSpace::Cell>
845 PointIterator itB, PointIterator itE )
847 std::cout <<
"<2,3> specialization" << std::endl;
848 std::unordered_set<typename KSpace::Cell> cells;
849 for (
auto it = itB; it != itE; ++it )
851 auto pointel =
K.uPointel( *it );
852 auto linelxp =
K.uIncident( pointel, 0,
true );
853 auto linelxm =
K.uIncident( pointel, 0,
false );
854 auto linelyp =
K.uIncident( pointel, 1,
true );
855 auto linelym =
K.uIncident( pointel, 1,
false );
856 cells.insert(
K.uIncident( linelxp, 1,
true ) );
857 cells.insert(
K.uIncident( linelxp, 1,
false ) );
858 cells.insert(
K.uIncident( linelxp, 2,
true ) );
859 cells.insert(
K.uIncident( linelxp, 2,
false ) );
860 cells.insert(
K.uIncident( linelxm, 1,
true ) );
861 cells.insert(
K.uIncident( linelxm, 1,
false ) );
862 cells.insert(
K.uIncident( linelxm, 2,
true ) );
863 cells.insert(
K.uIncident( linelxm, 2,
false ) );
864 cells.insert(
K.uIncident( linelyp, 2,
true ) );
865 cells.insert(
K.uIncident( linelyp, 2,
false ) );
866 cells.insert(
K.uIncident( linelym, 2,
true ) );
867 cells.insert(
K.uIncident( linelym, 2,
false ) );
877 template <
typename Po
intIterator>
882 PointIterator itB, PointIterator itE )
886 for (
auto it = itB; it != itE; ++it )
888 auto kp =
K.uKCoords(
K.uPointel( *it ) );
889 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] - 1, kp[ 2 ] );
890 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] - 1, kp[ 2 ] );
891 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] + 1, kp[ 2 ] );
892 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] + 1, kp[ 2 ] );
893 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] , kp[ 2 ] - 1 );
894 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] , kp[ 2 ] - 1 );
895 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] , kp[ 2 ] + 1 );
896 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] , kp[ 2 ] + 1 );
897 kpoints.emplace( kp[ 0 ] , kp[ 1 ] - 1, kp[ 2 ] - 1 );
898 kpoints.emplace( kp[ 0 ] , kp[ 1 ] + 1, kp[ 2 ] - 1 );
899 kpoints.emplace( kp[ 0 ] , kp[ 1 ] - 1, kp[ 2 ] + 1 );
900 kpoints.emplace( kp[ 0 ] , kp[ 1 ] + 1, kp[ 2 ] + 1 );
909 template <
typename TKSpace>
923 template <
typename Po
intelIterator>
925 std::unordered_set<typename KSpace::Cell>
927 PointelIterator itB, PointelIterator itE )
929 std::unordered_set<typename KSpace::Cell> cells;
930 for (
auto it = itB; it != itE; ++it )
933 auto linelxp =
K.uIncident( pointel, 0,
true );
934 auto linelxm =
K.uIncident( pointel, 0,
false );
935 auto surfxpyp =
K.uIncident( linelxp, 1,
true );
936 auto surfxpym =
K.uIncident( linelxp, 1,
false );
937 auto surfxmyp =
K.uIncident( linelxm, 1,
true );
938 auto surfxmym =
K.uIncident( linelxm, 1,
false );
939 cells.insert(
K.uIncident( surfxpyp, 2,
true ) );
940 cells.insert(
K.uIncident( surfxpyp, 2,
false ) );
941 cells.insert(
K.uIncident( surfxpym, 2,
true ) );
942 cells.insert(
K.uIncident( surfxpym, 2,
false ) );
943 cells.insert(
K.uIncident( surfxmyp, 2,
true ) );
944 cells.insert(
K.uIncident( surfxmyp, 2,
false ) );
945 cells.insert(
K.uIncident( surfxmym, 2,
true ) );
946 cells.insert(
K.uIncident( surfxmym, 2,
false ) );
957 template <
typename Po
intIterator>
959 std::unordered_set<typename KSpace::Cell>
961 PointIterator itB, PointIterator itE )
963 std::unordered_set<typename KSpace::Cell> cells;
964 for (
auto it = itB; it != itE; ++it )
966 auto pointel =
K.uPointel( *it );
967 auto linelxp =
K.uIncident( pointel, 0,
true );
968 auto linelxm =
K.uIncident( pointel, 0,
false );
969 auto surfxpyp =
K.uIncident( linelxp, 1,
true );
970 auto surfxpym =
K.uIncident( linelxp, 1,
false );
971 auto surfxmyp =
K.uIncident( linelxm, 1,
true );
972 auto surfxmym =
K.uIncident( linelxm, 1,
false );
973 cells.insert(
K.uIncident( surfxpyp, 2,
true ) );
974 cells.insert(
K.uIncident( surfxpyp, 2,
false ) );
975 cells.insert(
K.uIncident( surfxpym, 2,
true ) );
976 cells.insert(
K.uIncident( surfxpym, 2,
false ) );
977 cells.insert(
K.uIncident( surfxmyp, 2,
true ) );
978 cells.insert(
K.uIncident( surfxmyp, 2,
false ) );
979 cells.insert(
K.uIncident( surfxmym, 2,
true ) );
980 cells.insert(
K.uIncident( surfxmym, 2,
false ) );
990 template <
typename Po
intIterator>
995 PointIterator itB, PointIterator itE )
999 for (
auto it = itB; it != itE; ++it )
1001 auto kp =
K.uKCoords(
K.uPointel( *it ) );
1002 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] - 1, kp[ 2 ] - 1 );
1003 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] - 1, kp[ 2 ] - 1 );
1004 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] + 1, kp[ 2 ] - 1 );
1005 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] + 1, kp[ 2 ] - 1 );
1006 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] - 1, kp[ 2 ] + 1 );
1007 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] - 1, kp[ 2 ] + 1 );
1008 kpoints.emplace( kp[ 0 ] - 1, kp[ 1 ] + 1, kp[ 2 ] + 1 );
1009 kpoints.emplace( kp[ 0 ] + 1, kp[ 1 ] + 1, kp[ 2 ] + 1 );
1022#include "CellGeometry.ih"
1029#undef CellGeometry_RECURSES
Aim: Computes and stores sets of cells and provides methods to compute intersections of lattice and r...
static const Dimension dimension
Self & operator=(const Self &other)=default
UnorderedSetByBlock< Point, Splitter< Point, uint64_t > > myKPoints
CellGeometry & operator+=(const CellGeometry &other)
static bool includes(RandomIterator it2, RandomIterator itE2, RandomIterator it1, RandomIterator itE1)
bool subset(const CellGeometry &other) const
static Dimension dim(const Point &kp)
void addCellsTouchingPolytopePoints(const RationalPolytope &polytope)
Dimension maxCellDim() const
std::vector< Cell > getTouchedCells(const std::vector< Point > &points, const Dimension i) const
CellGeometry(const KSpace &K, Dimension min_cell_dim=0, Dimension max_cell_dim=KSpace::dimension, bool verbose=false)
std::vector< Point > getKPoints(const Dimension k) const
void addCellsTouchingPointels(PointelIterator itB, PointelIterator itE)
CellGeometry(Self &&other)=default
void init(const KSpace &K, Dimension min_cell_dim=0, Dimension max_cell_dim=KSpace::dimension, bool verbose=false)
std::vector< Point > getTouchedKPoints(const std::vector< Point > &points, const Dimension i) const
void addCellsTouchingPoints(PointIterator itB, PointIterator itE)
CellGeometry(const Self &other)=default
std::vector< Cell > getIntersectedCells(const LatticePolytope &polytope, const Dimension i) const
bool subset(const CellGeometry &other, const Dimension k) const
std::string className() const
Dimension minCellDim() const
DGtal::BigInteger BigInteger
DGtal::BoundedLatticePolytope< Space > Polytope
DGtal::BoundedLatticePolytope< Space > LatticePolytope
void addCellsTouchingPoint(const Point &p)
std::vector< Cell > getIntersectedCells(const RationalPolytope &polytope, const Dimension i) const
void addCellsTouchingPolytope(const LatticePolytope &polytope)
CellGeometry< TKSpace > Self
void addCellsTouchingPolytope(const RationalPolytope &polytope)
std::vector< Point > getIntersectedKPoints(const RationalPolytope &polytope, const Dimension i) const
DGtal::BoundedRationalPolytope< Space > RationalPolytope
std::vector< Point > getIntersectedKPoints(const LatticePolytope &polytope, const Dimension i) const
Size computeNbCells(const Dimension k) const
void addCellsTouchingPointel(const Cell &pointel)
void addCellsTouchingSegment(const Point &a, const Point &b)
void addCellsTouchingPolytopePoints(const LatticePolytope &polytope)
void addCellsTouchingCell(const Cell &c)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
Integer computeEuler() const
void selfDisplay(std::ostream &out) const
PointVector< dim, Integer > Point
NumberTraits< Integer >::UnsignedVersion Size
SpaceND< dim, Integer > Space
PointVector< dim, Integer > Vector
static const constexpr Dimension dimension
KhalimskyCell< dim, Integer > Cell
DGtal is the top-level namespace which contains all DGtal functions and types.
std::ostream & operator<<(std::ostream &out, const ClosedIntegerHalfPlane< TSpace > &object)
DGtal::uint32_t Dimension
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<>, boost::multiprecision::et_off > BigInteger
static UnorderedSetByBlock< typename KSpace::Point, Splitter< typename KSpace::Point, uint64_t > > getIncidentKPointsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
BOOST_STATIC_ASSERT(TKSpace::dimension==2)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPointels(const KSpace &K, PointelIterator itB, PointelIterator itE)
static UnorderedSetByBlock< typename KSpace::Point, Splitter< typename KSpace::Point, uint64_t > > getIncidentKPointsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPointels(const KSpace &K, PointelIterator itB, PointelIterator itE)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
BOOST_STATIC_ASSERT(TKSpace::dimension==3)
static UnorderedSetByBlock< typename KSpace::Point, Splitter< typename KSpace::Point, uint64_t > > getIncidentKPointsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
BOOST_STATIC_ASSERT(TKSpace::dimension==2)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPointels(const KSpace &K, PointelIterator itB, PointelIterator itE)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPointels(const KSpace &K, PointelIterator itB, PointelIterator itE)
BOOST_STATIC_ASSERT(TKSpace::dimension==2)
static UnorderedSetByBlock< typename KSpace::Point, Splitter< typename KSpace::Point, uint64_t > > getIncidentKPointsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
BOOST_STATIC_ASSERT(TKSpace::dimension==3)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPointels(const KSpace &K, PointelIterator itB, PointelIterator itE)
static UnorderedSetByBlock< typename KSpace::Point, Splitter< typename KSpace::Point, uint64_t > > getIncidentKPointsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPointels(const KSpace &K, PointelIterator itB, PointelIterator itE)
BOOST_CONCEPT_ASSERT((concepts::CCellularGridSpaceND< TKSpace >))
static std::unordered_set< typename KSpace::Cell > getIncidentCellsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
static UnorderedSetByBlock< typename KSpace::Point, Splitter< typename KSpace::Point, uint64_t > > getIncidentKPointsToPoints(const KSpace &K, PointIterator itB, PointIterator itE)
Aim: This concept describes a cellular grid space in nD. In these spaces obtained by cartesian produc...