Collapse of 3D cubical complex that is made of 20x20x20 voxels with their faces. Fixed cells were marked in red. It was the eight vertices, plus all border linels on the upper faces plus a random linel within the complex. The priority was the distance to the diagonal. Note that the Euler characteristic of the complex is unchanged after collapse.
#include <iostream>
#include <map>
#include "DGtal/base/Common.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/io/viewers/PolyscopeViewer.h"
#include "DGtal/topology/KhalimskySpaceND.h"
#include "DGtal/topology/CubicalComplex.h"
template <typename CubicalComplex>
{
double d1 = Point::diagonal( 1 ).dot( k1 ) / sqrt( (double) KSpace::dimension );
double d2 = Point::diagonal( 1 ).dot( k2 ) / sqrt( (double) KSpace::dimension );;
RealPoint v1( k1[ 0 ] - d1 * k1[ 0 ], k1[ 1 ] - d1 * k1[ 1 ], k1[ 2 ] - d1 * k1[ 2 ] );
RealPoint v2( k2[ 0 ] - d2 * k2[ 0 ], k2[ 1 ] - d2 * k2[ 1 ], k2[ 2 ] - d2 * k2[ 2 ] );
double n1 = v1.
dot( v1 );
double n2 = v2.
dot( v2 );
return ( n1 < n2 ) || ( ( n1 == n2 ) && ( it1->first < it2->first ) );
}
};
int main(
int argc,
char** argv )
{
typedef std::map<Cell, CubicalCellData>
Map;
std::vector<Cell> S;
{
S.push_back(
K.uCell( k1 ) );
double d1 = Point::diagonal( 1 ).dot( k1 ) / (double) KSpace::dimension;
v1 -= d1 * RealPoint::diagonal( 1.0 );
double n1 = v1.norm();
bool fixed = ( ( x == 0 ) && ( y == 0 ) && ( z == 0 ) )
|| ( ( x == 0 ) && ( y == m ) && ( z == 0 ) )
|| ( ( x == m ) && ( y == 0 ) && ( z == 0 ) )
|| ( ( x == m ) && ( y == m ) && ( z == 0 ) )
|| ( ( x == m/3 ) && ( y == 2*m/3 ) && ( z == 2*m/3 ) )
|| ( ( x == 0 ) && ( y == 0 ) && ( z == m ) )
|| ( ( x == 0 ) && ( y == m ) && ( z == m ) )
|| ( ( x == m ) && ( y == 0 ) && ( z == m ) )
|| ( ( x == m ) && ( y == m ) && ( z == m ) )
|| ( ( x == 0 ) && ( y == m ) )
|| ( ( x == m ) && ( y == m ) )
|| ( ( z == 0 ) && ( y == m ) )
|| ( ( z == m ) && ( y == m ) );
complex.insertCell( S.back(),
fixed ? CC::FIXED
);
}
trace.
info() <<
"After close: " << complex << std::endl;
{
it != itE; ++it )
{
bool fixed = (it->second.data == CC::FIXED);
if ( fixed ) viewer.drawColor( Color::Red );
else viewer.drawColor( Color::White );
viewer << it->first;
}
viewer.show();
}
CC::DefaultCellMapIteratorPriority P;
= functions::collapse( complex, S.begin(), S.end(), P, true, true, true );
trace.
info() <<
"Collapse removed " << removed <<
" cells." << std::endl;
trace.
info() <<
"After collapse: " << complex << std::endl;
{
it != itE; ++it )
{
bool fixed = (it->second.data == CC::FIXED);
if ( fixed ) viewer.drawColor( Color::Red );
else viewer.drawColor( Color::White );
viewer << it->first;
}
viewer.show();
return 0;
}
}
Aim: This class represents an arbitrary cubical complex living in some Khalimsky space....
const KSpace & space() const
TKSpace KSpace
Type of the cellular grid space.
KSpace::Cell Cell
Type for a cell in the space.
KSpace::Point Point
Type for a point in the digital space.
CellMap::iterator CellMapIterator
Iterator for visiting type CellMap.
auto dot(const PointVector< dim, OtherComponent, OtherStorage > &v) const -> decltype(DGtal::dotProduct(*this, v))
Dot product with a PointVector.
void beginBlock(const std::string &keyword="")
Point::Coordinate Integer
Z3i this namespace gathers the standard of types for 3D imagery.
DGtal is the top-level namespace which contains all DGtal functions and types.
std::uint64_t uint64_t
unsigned 64-bit integer.
std::uint32_t uint32_t
unsigned 32-bit integer.
DGtal::uint32_t Dimension
CubicalComplex::KSpace KSpace
bool operator()(const CellMapIterator &it1, const CellMapIterator &it2) const
CubicalComplex::Point Point
CubicalComplex::Cell Cell
const CubicalComplex & myComplex
CubicalComplex::CellMapIterator CellMapIterator
std::unordered_map< Cell, CubicalCellData > Map
CubicalComplex< KSpace, Map > CC
CC::CellMapConstIterator CellMapConstIterator
PointVector< 3, double > RealPoint
PolyscopeViewer< Space, KSpace > MyViewer