34 #include "DGtal/base/Common.h"
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/geometry/volumes/ConvexityHelper.h"
37 #include "DGtal/shapes/SurfaceMesh.h"
38 #include "DGtalCatch.h"
42 using namespace DGtal;
50 "[convexity_helper][lattice_polytope][2d]" )
55 GIVEN(
"Given a star { (0,0), (-4,-1), (-3,5), (7,3), (5, -2) } " ) {
58 WHEN(
"Computing its lattice polytope" ){
59 const auto P = Helper::computeLatticePolytope( V,
false,
true );
61 THEN(
"The polytope is valid and has 4 non trivial facets" ) {
62 REQUIRE( P.nbHalfSpaces() - 4 == 4 );
64 THEN(
"The polytope is Minkowski summable" ) {
67 THEN(
"The polytope contains the input points" ) {
68 REQUIRE( P.isInside( V[ 0 ] ) );
69 REQUIRE( P.isInside( V[ 1 ] ) );
70 REQUIRE( P.isInside( V[ 2 ] ) );
71 REQUIRE( P.isInside( V[ 3 ] ) );
72 REQUIRE( P.isInside( V[ 4 ] ) );
74 THEN(
"The polytope contains 58 points" ) {
77 THEN(
"The interior of the polytope contains 53 points" ) {
78 REQUIRE( P.countInterior() == 53 );
80 THEN(
"The boundary of the polytope contains 5 points" ) {
81 REQUIRE( P.countBoundary() == 5 );
85 GIVEN(
"Given a square with an additional outside vertex " ) {
89 WHEN(
"Computing its Delaunay cell complex" ){
90 CvxCellComplex complex;
91 bool ok = Helper::computeDelaunayCellComplex( complex, V,
false );
93 THEN(
"The complex has 2 cells, 6 faces, 5 vertices" ) {
95 REQUIRE( complex.nbCells() == 2 );
96 REQUIRE( complex.nbFaces() == 6 );
97 REQUIRE( complex.nbVertices() == 5 );
99 THEN(
"The faces of cells are finite" ) {
100 bool ok_finite =
true;
101 for (
auto c = 0; c < complex.nbCells(); ++c ) {
102 const auto faces = complex.cellFaces( c );
103 for (
auto f : faces )
104 ok_finite = ok_finite && ! complex.isInfinite( complex.faceCell( f ) );
108 THEN(
"The opposite of faces of cells are infinite except two" ) {
110 for (
auto c = 0; c < complex.nbCells(); ++c ) {
111 const auto faces = complex.cellFaces( c );
112 for (
auto f : faces ) {
113 const auto opp_f = complex.opposite( f );
114 nb_finite += complex.isInfinite( complex.faceCell( opp_f ) ) ? 0 : 1;
128 "[convexity_helper][3d]" )
137 GIVEN(
"Given an octahedron star { (0,0,0), (-2,0,0), (2,0,0), (0,-2,0), (0,2,0), (0,0,-2), (0,0,2) } " ) {
139 = {
Point(0,0,0),
Point(-2,0,0),
Point(2,0,0),
Point(0,-2,0),
Point(0,2,0),
141 WHEN(
"Computing its lattice polytope" ){
142 const auto P = Helper::computeLatticePolytope( V,
false,
true );
144 THEN(
"The polytope is valid and has 8 non trivial facets plus 12 edge constraints" ) {
145 REQUIRE( P.nbHalfSpaces() - 6 == 20 );
147 THEN(
"The polytope is Minkowski summable" ) {
150 THEN(
"The polytope contains the input points" ) {
151 REQUIRE( P.isInside( V[ 0 ] ) );
152 REQUIRE( P.isInside( V[ 1 ] ) );
153 REQUIRE( P.isInside( V[ 2 ] ) );
154 REQUIRE( P.isInside( V[ 3 ] ) );
155 REQUIRE( P.isInside( V[ 4 ] ) );
156 REQUIRE( P.isInside( V[ 5 ] ) );
157 REQUIRE( P.isInside( V[ 6 ] ) );
159 THEN(
"The polytope contains 25 points" ) {
162 THEN(
"The interior of the polytope contains 7 points" ) {
163 REQUIRE( P.countInterior() == 7 );
165 THEN(
"The boundary of the polytope contains 18 points" ) {
166 REQUIRE( P.countBoundary() == 18 );
169 WHEN(
"Computing the boundary of its convex hull as a SurfaceMesh" ){
171 bool ok = Helper::computeConvexHullBoundary( smesh, V,
false );
173 THEN(
"The surface mesh is valid and has 6 vertices, 12 edges and 8 faces" ) {
175 REQUIRE( smesh.nbVertices() == 6 );
176 REQUIRE( smesh.nbEdges() == 12 );
177 REQUIRE( smesh.nbFaces() == 8 );
179 THEN(
"The surface mesh has the topology of a sphere" ) {
181 REQUIRE( smesh.computeManifoldBoundaryEdges().size() == 0 );
182 REQUIRE( smesh.computeNonManifoldEdges().size() == 0 );
185 WHEN(
"Computing the boundary of its convex hull as a lattice PolygonalSurface" ){
186 LatticePolySurf lpsurf;
187 bool ok = Helper::computeConvexHullBoundary( lpsurf, V,
false );
189 THEN(
"The polygonal surface is valid and has 6 vertices, 12 edges and 8 faces" ) {
191 REQUIRE( lpsurf.nbVertices() == 6 );
192 REQUIRE( lpsurf.nbEdges() == 12 );
193 REQUIRE( lpsurf.nbFaces() == 8 );
194 REQUIRE( lpsurf.nbArcs() == 24 );
196 THEN(
"The polygonal surface has the topology of a sphere and no boundary" ) {
197 REQUIRE( lpsurf.Euler() == 2 );
198 REQUIRE( lpsurf.allBoundaryArcs().size() == 0 );
199 REQUIRE( lpsurf.allBoundaryVertices().size() == 0 );
202 WHEN(
"Computing its convex hull as a ConvexCellComplex" ){
203 CvxCellComplex complex;
204 bool ok = Helper::computeConvexHullCellComplex( complex, V,
false );
206 THEN(
"The convex cell complex is valid and has 6 vertices, 8 faces and 1 finite cell" ) {
208 REQUIRE( complex.nbVertices() == 6 );
209 REQUIRE( complex.nbFaces() == 8 );
210 REQUIRE( complex.nbCells() == 1 );
214 GIVEN(
"Given a cube with an additional outside vertex " ) {
216 = {
Point(-10,-10,-10),
Point(10,-10,-10),
Point(-10,10,-10),
Point(10,10,-10),
217 Point(-10,-10,10),
Point(10,-10,10),
Point(-10,10,10),
Point(10,10,10),
219 WHEN(
"Computing its Delaunay cell complex" ){
220 CvxCellComplex complex;
221 bool ok = Helper::computeDelaunayCellComplex( complex, V,
false );
223 THEN(
"The complex has 2 cells, 10 faces, 9 vertices" ) {
225 REQUIRE( complex.nbCells() == 2 );
226 REQUIRE( complex.nbFaces() == 10 );
227 REQUIRE( complex.nbVertices() == 9 );
229 THEN(
"The faces of cells are finite" ) {
230 bool ok_finite =
true;
231 for (
auto c = 0; c < complex.nbCells(); ++c ) {
232 const auto faces = complex.cellFaces( c );
233 for (
auto f : faces )
234 ok_finite = ok_finite && ! complex.isInfinite( complex.faceCell( f ) );
238 THEN(
"The opposite of faces of cells are infinite except two" ) {
240 for (
auto c = 0; c < complex.nbCells(); ++c ) {
241 const auto faces = complex.cellFaces( c );
242 for (
auto f : faces ) {
243 const auto opp_f = complex.opposite( f );
244 nb_finite += complex.isInfinite( complex.faceCell( opp_f ) ) ? 0 : 1;
Aim: Represents a polygon mesh, i.e. a 2-dimensional combinatorial surface whose faces are (topologic...
DGtal is the top-level namespace which contains all DGtal functions and types.
Z3i::RealVector RealVector
Aim: represents a d-dimensional complex in a d-dimensional space with the following properties and re...
Aim: Provides a set of functions to facilitate the computation of convex hulls and polytopes,...
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
SCENARIO("ConvexityHelper< 2 > unit tests", "[convexity_helper][lattice_polytope][2d]")
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))