34#include "DGtal/base/Common.h"
35#include "DGtal/kernel/SpaceND.h"
36#include "DGtal/topology/KhalimskySpaceND.h"
37#include "DGtal/geometry/volumes/CellGeometry.h"
38#include "DGtal/geometry/volumes/DigitalConvexity.h"
39#include "DGtalCatch.h"
50SCENARIO(
"DigitalConvexity< Z2 > unit tests",
"[digital_convexity][2d]" )
56 DConvexity dconv(
Point( -5, -5 ),
Point( 10, 10 ) );
58 GIVEN(
"Given a fat simplex { (0,0), (4,-1), (2,5) } " ) {
60 auto vertex_cover = dconv.
makeCellCover( V.begin(), V.end() );
61 auto fat_simplex = dconv.
makeSimplex ( V.begin(), V.end() );
64 auto point_cover = dconv.
makeCellCover( inside_pts.begin(), inside_pts.end() );
65 THEN(
"The fat simplex is not degenerated." ) {
68 THEN(
"Its vertex cover contains 3 0-cells, 12 1-cells, 12 2-cells" ) {
69 REQUIRE( vertex_cover.computeNbCells( 0 ) == 3 );
70 REQUIRE( vertex_cover.computeNbCells( 1 ) == 12 );
71 REQUIRE( vertex_cover.computeNbCells( 2 ) == 12 );
73 THEN(
"Its vertex cover is a subset of its point cover" ) {
74 REQUIRE( vertex_cover.subset( point_cover ) );
76 THEN(
"Its point cover is a subset of its simplex cover" ) {
77 REQUIRE( point_cover.subset( simplex_cover ) );
79 THEN(
"Being fat, its simplex cover is equal to its point cover" ) {
80 REQUIRE( simplex_cover.subset( point_cover ) );
83 GIVEN(
"Given a thin simplex { (0,0), (4,3), (7,5) } " ) {
85 auto vertex_cover = dconv.
makeCellCover( V.begin(), V.end() );
86 auto thin_simplex = dconv.
makeSimplex ( V.begin(), V.end() );
89 auto point_cover = dconv.
makeCellCover( inside_pts.begin(), inside_pts.end() );
90 THEN(
"The thin simplex is not degenerated." ) {
93 THEN(
"Its vertex cover contains 3 0-cells, 12 1-cells, 12 2-cells" ) {
94 REQUIRE( vertex_cover.computeNbCells( 0 ) == 3 );
95 REQUIRE( vertex_cover.computeNbCells( 1 ) == 12 );
96 REQUIRE( vertex_cover.computeNbCells( 2 ) == 12 );
98 THEN(
"Its vertex cover is a subset of its point cover" ) {
99 REQUIRE( vertex_cover.subset( point_cover ) );
101 THEN(
"Its point cover is a subset of its simplex cover" ) {
102 REQUIRE( point_cover.subset( simplex_cover ) );
104 THEN(
"Being thin, its simplex cover is not equal to its point cover for 1<=dim<=2" ) {
105 REQUIRE( ! simplex_cover.subset( point_cover ) );
106 REQUIRE( simplex_cover.subset( point_cover, 0 ) );
107 REQUIRE( ! simplex_cover.subset( point_cover, 1 ) );
108 REQUIRE( ! simplex_cover.subset( point_cover, 2 ) );
113SCENARIO(
"DigitalConvexity< Z2 > fully convex triangles",
"[convex_simplices][2d]" )
122 DConvexity dconv(
Point( -1, -1 ),
Point( 5, 5 ) );
124 WHEN(
"Computing all triangles in domain (0,0)-(4,4)." ) {
125 unsigned int nb_notsimplex = 0;
126 unsigned int nb_invalid = 0;
127 unsigned int nb_degenerated= 0;
128 unsigned int nb_common = 0;
129 unsigned int nb_unitary = 0;
136 nb_degenerated += tri_type == DConvexity::SimplexType::DEGENERATED ? 1 : 0;
137 nb_invalid += tri_type == DConvexity::SimplexType::INVALID ? 1 : 0;
138 nb_unitary += tri_type == DConvexity::SimplexType::UNITARY ? 1 : 0;
139 nb_common += tri_type == DConvexity::SimplexType::COMMON ? 1 : 0;
141 THEN(
"All 2737 invalid triangles are degenerated " ) {
143 REQUIRE( nb_notsimplex == nb_degenerated );
144 REQUIRE( nb_degenerated == 2737 );
146 THEN(
"There are 12888 valid triangles" ) {
147 REQUIRE( nb_unitary + nb_common == 12888 );
149 THEN(
"There are fewer (1920) unitary triangles than common triangles (10968)" ) {
152 REQUIRE( nb_unitary < nb_common );
154 THEN(
"The total number of triangles (unitary, common, degenerated) is (domain size)^3, i.e. 5^6" ) {
155 REQUIRE( nb_unitary + nb_common + nb_degenerated == 5*5*5*5*5*5 );
158 WHEN(
"Computing all triangles in domain (0,0)-(4,4)." ) {
159 unsigned int nbsimplex= 0;
160 unsigned int nb0 = 0;
161 unsigned int nb1 = 0;
162 unsigned int nb2 = 0;
163 unsigned int nb01_not2 = 0;
168 if ( ! ( ( a < b ) && ( b < c ) ) )
continue;
171 bool cvx0 = dconv.
isKConvex( triangle, 0 );
172 bool cvx1 = dconv.
isKConvex( triangle, 1 );
173 bool cvx2 = dconv.
isKConvex( triangle, 2 );
178 nb01_not2 += ( cvx0 && cvx1 && ! cvx2 ) ? 1 : 0;
180 THEN(
"All valid triangles are 0-convex." ) {
183 THEN(
"There are less 1-convex and 2-convex than 0-convex." ) {
187 THEN(
"When the triangle is 0-convex and 1-convex, then it is 2-convex." ) {
193SCENARIO(
"DigitalConvexity< Z3 > fully convex tetrahedra",
"[convex_simplices][3d]" )
202 DConvexity dconv(
Point( -1, -1, -1 ),
Point( 4, 4, 4 ) );
204 WHEN(
"Computing all lexicographically ordered tetrahedra anchored at (0,0,0) in domain (0,0,0)-(3,3,3)." ) {
205 unsigned int nb_notsimplex = 0;
206 unsigned int nb_invalid = 0;
207 unsigned int nb_degenerated= 0;
208 unsigned int nb_common = 0;
209 unsigned int nb_unitary = 0;
215 if ( ! ( ( a < b ) && ( b < c ) && ( c < d ) ) )
continue;
217 auto tri_type = dconv.
simplexType( { a, b, c, d } );
218 nb_degenerated += tri_type == DConvexity::SimplexType::DEGENERATED ? 1 : 0;
219 nb_invalid += tri_type == DConvexity::SimplexType::INVALID ? 1 : 0;
220 nb_unitary += tri_type == DConvexity::SimplexType::UNITARY ? 1 : 0;
221 nb_common += tri_type == DConvexity::SimplexType::COMMON ? 1 : 0;
223 THEN(
"All 4228 invalid tetrahedra are degenerated " ) {
225 REQUIRE( nb_notsimplex == nb_degenerated );
226 REQUIRE( nb_degenerated == 4228 );
228 THEN(
"There are 35483 valid tetrahedra" ) {
229 REQUIRE( nb_unitary + nb_common == 35483 );
231 THEN(
"There are fewer (2515) unitary triangles than common triangles (32968)" ) {
234 REQUIRE( nb_unitary < nb_common );
236 THEN(
"The total number of triangles (unitary, common, degenerated) is 39711" ) {
237 REQUIRE( nb_unitary + nb_common + nb_degenerated == 39711 );
240 WHEN(
"Computing many tetrahedra in domain (0,0,0)-(4,4,4)." ) {
241 const unsigned int nb = 50;
242 unsigned int nbsimplex= 0;
243 unsigned int nb0 = 0;
244 unsigned int nb1 = 0;
245 unsigned int nb2 = 0;
246 unsigned int nb3 = 0;
247 unsigned int nb012_not3 = 0;
248 unsigned int nbf = 0;
249 unsigned int nbfg = 0;
250 unsigned int nbffast = 0;
251 unsigned int nb0123 = 0;
252 for (
unsigned int i = 0; i < nb; ++i )
254 Point a( rand() % 5, rand() % 5, rand() % 5 );
255 Point b( rand() % 5, rand() % 5, rand() % 5 );
256 Point c( rand() % 5, rand() % 5, rand() % 5 );
257 Point d( rand() % 5, rand() % 5, rand() % 5 );
260 std::vector< Point > X;
269 if ( cvxf != cvxfg || cvxf != cvxffast) {
270 std::cout <<
"[" << cvx0 << cvx1 << cvx2 << cvx3 <<
"] "
271 <<
"[" << cvxf <<
"] [" << cvxfg
272 <<
"] [" << cvxffast <<
"]"
273 << a << b << c << d << std::endl;
281 nbfg += cvxfg ? 1 : 0;
282 nbffast += cvxffast ? 1 : 0;
283 nb0123 += ( cvx0 && cvx1 && cvx2 && cvx3 ) ? 1 : 0;
284 nb012_not3+= ( cvx0 && cvx1 && cvx2 && ! cvx3 ) ? 1 : 0;
286 THEN(
"All valid tetrahedra are 0-convex." ) {
289 THEN(
"There are less 1-convex, 2-convex and 3-convex than 0-convex." ) {
294 THEN(
"When the tetrahedron is 0-convex, 1-convex and 2-convex, then it is 3-convex." ) {
300 THEN(
"All methods for computing full convexity agree." ) {
307SCENARIO(
"DigitalConvexity< Z3 > rational fully convex tetrahedra",
"[convex_simplices][3d][rational]" )
314 DConvexity dconv(
Point( -1, -1, -1 ),
Point( 10, 10, 10 ) );
315 WHEN(
"Computing many tetrahedra in domain (0,0,0)-(4,4,4)." ) {
316 const unsigned int nb = 50;
317 unsigned int nbsimplex= 0;
318 unsigned int nb0 = 0;
319 unsigned int nb1 = 0;
320 unsigned int nb2 = 0;
321 unsigned int nb3 = 0;
322 unsigned int nb012_not3 = 0;
323 unsigned int nbf = 0;
324 unsigned int nb0123 = 0;
325 for (
unsigned int i = 0; i < nb; ++i )
327 Point a( 2*(rand() % 10), rand() % 20, 2*(rand() % 10) );
328 Point b( rand() % 20, 2*(rand() % 10), 2*(rand() % 10) );
329 Point c( 2*(rand() % 10), 2*(rand() % 10), rand() % 20 );
330 Point d( 2*(rand() % 10), 2*(rand() % 10), 2*(rand() % 10) );
344 nb0123 += ( cvx0 && cvx1 && cvx2 && cvx3 ) ? 1 : 0;
345 nb012_not3+= ( cvx0 && cvx1 && cvx2 && ! cvx3 ) ? 1 : 0;
347 THEN(
"All valid tetrahedra are 0-convex." ) {
350 THEN(
"There are less 1-convex, 2-convex and 3-convex than 0-convex." ) {
355 THEN(
"When the tetrahedron is 0-convex, 1-convex and 2-convex, then it is 3-convex." ) {
370SCENARIO(
"DigitalConvexity< Z2 > rational fully convex tetrahedra",
"[convex_simplices][2d][rational]" )
377 DConvexity dconv(
Point( -1, -1 ),
Point( 10, 10 ) );
378 WHEN(
"Computing many triangle in domain (0,0)-(9,9)." ) {
379 const unsigned int nb = 50;
380 unsigned int nbsimplex= 0;
381 unsigned int nb0 = 0;
382 unsigned int nb1 = 0;
383 unsigned int nb2 = 0;
384 unsigned int nb01_not2 = 0;
385 unsigned int nbf = 0;
386 unsigned int nb012 = 0;
387 for (
unsigned int i = 0; i < nb; ++i )
389 Point a( 2*(rand() % 10), rand() % 20 );
390 Point b( rand() % 20 , 2*(rand() % 10) );
391 Point c( 2*(rand() % 10), 2*(rand() % 10) );
403 nb012 += ( cvx0 && cvx1 && cvx2 ) ? 1 : 0;
404 nb01_not2 += ( cvx0 && cvx1 && ! cvx2 ) ? 1 : 0;
406 THEN(
"All valid tetrahedra are 0-convex." ) {
409 THEN(
"There are less 1-convex, 2-convex than 0-convex." ) {
413 THEN(
"When the tetrahedron is 0-convex, and 1-convex, then it is 2-convex." ) {
426SCENARIO(
"DigitalConvexity< Z3 > full subconvexity of segments and triangles",
"[subconvexity][3d]" )
435 DConvexity dconv(
Point( -6, -6, -6 ),
Point( 6, 6, 6 ) );
437 WHEN(
"Computing many tetrahedra" ) {
438 const unsigned int nb = 50;
439 unsigned int nb_fulldim = 0;
440 unsigned int nb_ok_seg = 0;
441 unsigned int nb_ok_tri = 0;
442 for (
unsigned int l = 0; l < nb; ++l )
444 const Point a { (rand() % 10 - 5), (rand() % 10 - 5), (rand() % 10 - 5) };
445 const Point b { (rand() % 10 - 5), (rand() % 10 - 5), (rand() % 10 - 5) };
446 const Point c { (rand() % 10 - 5), (rand() % 10 - 5), (rand() % 10 - 5) };
447 const Point d { (rand() % 10 - 5), (rand() % 10 - 5), (rand() % 10 - 5) };
448 const std::vector<Point> pts = { a, b, c, d };
450 nb_fulldim += fulldim ? 1 : 0;
451 if ( ! fulldim )
continue;
452 auto simplex = dconv.
makeSimplex( pts.cbegin(), pts.cend() );
455 unsigned int nb_subconvex = 0;
456 unsigned int nb_total = 0;
457 for (
unsigned int i = 0; i < 4; i++ )
458 for (
unsigned int j = i+1; j < 4; j++ )
460 auto segment = dconv.
makeSimplex( { pts[ i ], pts[ j ] } );
462 nb_subconvex += ok ? 1 : 0;
465 trace.
info() <<
"****** SEGMENT NOT SUBCONVEX ******" << std::endl;
466 trace.
info() <<
"splx v =" << a << b << c << d << std::endl;
467 trace.
info() <<
"simplex=" << simplex << std::endl;
468 trace.
info() <<
"seg v =" << pts[ i ] << pts[ j ] << std::endl;
469 trace.
info() <<
"segment=" << segment << std::endl;
472 nb_ok_seg += ( nb_subconvex == nb_total ) ? 1 : 0;
475 unsigned int nb_subconvex = 0;
476 unsigned int nb_total = 0;
477 for (
unsigned int i = 0; i < 4; i++ )
478 for (
unsigned int j = i+1; j < 4; j++ )
479 for (
unsigned int k = j+1; k < 4; k++ )
481 auto triangle = dconv.
makeSimplex({ pts[ i ], pts[ j ], pts[ k ] });
483 nb_subconvex += ok ? 1 : 0;
486 trace.
info() <<
"****** TRIANGLE NOT SUBCONVEX ****" << std::endl;
487 trace.
info() <<
"splx v =" << a << b << c << d << std::endl;
488 trace.
info() <<
"simplex=" << simplex << std::endl;
489 trace.
info() <<
"tri v =" << pts[ i ] << pts[ j ]
490 << pts[ k ] << std::endl;
491 trace.
info() <<
"triangle=" << triangle << std::endl;
494 nb_ok_tri += ( nb_subconvex == nb_total ) ? 1 : 0;
497 THEN(
"At least half the tetrahedra are full dimensional." ) {
498 REQUIRE( nb_fulldim >= nb / 2 );
500 THEN(
"All segments of a tetrahedron should be subconvex to it." ) {
501 REQUIRE( nb_ok_seg == nb_fulldim );
503 THEN(
"All triangles of a tetrahedron should be subconvex to it." ) {
504 REQUIRE( nb_ok_tri == nb_fulldim );
509SCENARIO(
"DigitalConvexity< Z3 > full convexity of polyhedra",
"[full_convexity][3d]" )
518 DConvexity dconv(
Point( -36, -36, -36 ),
Point( 36, 36, 36 ) );
520 const unsigned int nb = 10;
521 unsigned int nbfg = 0;
522 unsigned int nbffast = 0;
523 unsigned int nbfenv = 0;
525 std::vector< PointRange > XX;
526 for (
unsigned int i = 0; i < nb; ++i )
528 unsigned int k = 100;
530 for (
unsigned int j = 0; j < k; ++ j )
531 X[ j ] =
Point( rand() % 10, rand() % 10, rand() % 10 );
539 for (
const auto& X : XX )
542 nbfg += fcvx ? 1 : 0;
544 double t1 = c.stopClock();
546 for (
const auto& X : XX )
549 nbffast += fcvx ? 1 : 0;
551 double t2 = c.stopClock();
553 for (
const auto& X : XX )
555 auto card = dconv.
envelope( X ).size();
556 bool fcvx = card == X.size();
557 nbfenv += fcvx ? 1 : 0;
559 double t3 = c.stopClock();
560 WHEN(
"Computing many polytopes." ) {
561 THEN(
"All three methods agree on full convexity results" ) {
572SCENARIO(
"DigitalConvexity< Z4 > full convexity of polyhedra",
"[full_convexity][4d]" )
581 DConvexity dconv(
Point( -36, -36, -36, -36 ),
Point( 36, 36, 36, 36 ) );
583 const unsigned int nb = 4;
584 unsigned int nbfg = 0;
585 unsigned int nbffast = 0;
586 unsigned int nbfenv = 0;
588 std::vector< PointRange > XX;
589 for (
unsigned int i = 0; i < nb; ++i )
591 unsigned int k = 100;
593 for (
unsigned int j = 0; j < k; ++ j )
594 X[ j ] =
Point( rand() % 8, rand() % 8, rand() % 8, rand() % 8 );
602 for (
const auto& X : XX )
605 nbfg += fcvx ? 1 : 0;
607 double t1 = c.stopClock();
609 for (
const auto& X : XX )
612 nbffast += fcvx ? 1 : 0;
614 double t2 = c.stopClock();
616 for (
const auto& X : XX )
618 auto card = dconv.
envelope( X ).size();
619 bool fcvx = card == X.size();
620 nbfenv += fcvx ? 1 : 0;
622 double t3 = c.stopClock();
623 WHEN(
"Computing many polytopes." ) {
624 THEN(
"All three methods agree on full convexity results" ) {
634SCENARIO(
"DigitalConvexity< Z2 > sub-convexity of polyhedra",
"[full_subconvexity][2d]" )
642 DConvexity dconv(
Point( -36, -36 ),
Point( 36, 36 ) );
644 std::vector< Point > X( k );
645 X[ 0 ] =
Point( 0,0 );
646 X[ 1 ] =
Point( 7,-2 );
647 X[ 2 ] =
Point( 3,6 );
648 X[ 3 ] =
Point( 5, 5 );
649 X[ 4 ] =
Point( 2, 3 );
650 X[ 5 ] =
Point( -1, 1 );
654 REQUIRE( CG.nbCells() == L.size() );
655 for (
int i = 0; i < k; i++ )
656 for (
int j = i+1; j < k; j++ )
658 std::vector< Point > Z { X[ i ], X[ j ] };
664 REQUIRE( tangent_old == tangent_new );
665 REQUIRE( tangent_ab_old == tangent_ab_new );
666 REQUIRE( tangent_new == tangent_ab_new );
670SCENARIO(
"DigitalConvexity< Z3 > sub-convexity of polyhedra",
"[full_subconvexity][3d]" )
678 DConvexity dconv(
Point( -36, -36, -36 ),
Point( 36, 36, 36 ) );
679 std::vector< Point > X( 5 );
680 X[ 0 ] =
Point( 0,0,0 );
681 X[ 1 ] =
Point( 0,5,1 );
682 X[ 2 ] =
Point( 2,1,6 );
683 X[ 3 ] =
Point( 6,1,1 );
684 X[ 4 ] =
Point( -2,-2,-3 );
688 std::vector< Point > Y;
690 REQUIRE( CG.nbCells() == L.size() );
692 unsigned int nb_ok = 0;
693 unsigned int nb_tgt= 0;
694 for (
int i = 0; i < 100; i++ )
696 Point a( rand() % 6, rand() % 6, rand() % 6 );
697 Point b( rand() % 6, rand() % 6, rand() % 6 );
701 nb_tgt += tangent_ab_new ? 1 : 0;
702 nb_ok += ( tangent_ab_old == tangent_ab_new ) ? 1 : 0;
710SCENARIO(
"DigitalConvexity< Z3 > envelope",
"[envelope][3d]" )
718 DConvexity dconv(
Point( -36, -36, -36 ),
Point( 36, 36, 36 ) );
720 WHEN(
"Computing the envelope Z of a digital set X with direct algorithm" ) {
721 THEN(
"Z contains X" ){
722 for (
int k = 0; k < 5; k++ )
724 int n = 3 + ( rand() % 7 );
726 for (
int i = 0; i < n; i++ )
727 S.insert(
Point( rand() % 10, rand() % 10, rand() % 10 ) );
728 std::vector< Point > X( S.cbegin(), S.cend() );
730 auto Z = dconv.
envelope( X, DConvexity::EnvelopeAlgorithm::DIRECT );
733 bool Z_includes_X = std::includes( Z.cbegin(), Z.cend(),
734 X.cbegin(), X.cend() );
735 REQUIRE( X.size() <= Z.size() );
738 THEN(
"Z is fully convex" ){
739 for (
int k = 0; k < 5; k++ )
741 int n = 3 + ( rand() % 7 );
743 for (
int i = 0; i < n; i++ )
744 S.insert(
Point( rand() % 10, rand() % 10, rand() % 10 ) );
745 std::vector< Point > X( S.cbegin(), S.cend() );
753 WHEN(
"Computing the envelope Z of a digital set X with LatticeSet algorithm" ) {
754 THEN(
"Z contains X" ){
755 for (
int k = 0; k < 5; k++ )
757 int n = 3 + ( rand() % 7 );
759 for (
int i = 0; i < n; i++ )
760 S.insert(
Point( rand() % 10, rand() % 10, rand() % 10 ) );
761 std::vector< Point > X( S.cbegin(), S.cend() );
762 auto Z = dconv.
envelope( X, DConvexity::EnvelopeAlgorithm::LATTICE_SET );
764 bool Z_includes_X = std::includes( Z.cbegin(), Z.cend(),
765 X.cbegin(), X.cend() );
766 REQUIRE( X.size() <= Z.size() );
769 THEN(
"Z is fully convex" ){
770 for (
int k = 0; k < 5; k++ )
772 int n = 3 + ( rand() % 7 );
774 for (
int i = 0; i < n; i++ )
775 S.insert(
Point( rand() % 10, rand() % 10, rand() % 10 ) );
776 std::vector< Point > X( S.cbegin(), S.cend() );
786SCENARIO(
"DigitalConvexity< Z2 > envelope",
"[envelope][2d]" )
794 DConvexity dconv(
Point( -360, -360 ),
Point( 360, 360 ) );
796 WHEN(
"Computing the envelope Z of two points" ) {
797 THEN(
"it requires at most one iteration" ){
798 for (
int k = 0; k < 10; k++ )
800 std::vector< Point > X;
801 X.push_back(
Point( rand() % 100, rand() % 100 ) );
802 X.push_back(
Point( rand() % 100, rand() % 100 ) );
803 std::sort( X.begin(), X.end() );
811SCENARIO(
"DigitalConvexity< Z2 > relative envelope",
"[rel_envelope][2d]" )
819 DConvexity dconv(
Point( -360, -360 ),
Point( 360, 360 ) );
821 std::vector< Point > X {
Point( -10, -7 ),
Point( 10, 7 ) };
822 std::vector< Point > Y {
Point( -11, -6 ),
Point( 9, 8 ) };
823 std::sort( X.begin(), X.end() );
824 std::sort( Y.begin(), Y.end() );
829 WHEN(
"Computing the envelope of X relative to Y and Y relative to X" ) {
832 THEN(
"Both sets are fully convex" ){
836 THEN(
"There are inclusion rules between sets" ){
839 REQUIRE( std::includes( Y.cbegin(), Y.cend(),
840 FC_X_rel_Y.cbegin(), FC_X_rel_Y.cend() ) );
841 REQUIRE( std::includes( X.cbegin(), X.cend(),
842 FC_Y_rel_X.cbegin(), FC_Y_rel_X.cend() ) );
845 WHEN(
"Computing the envelope of X relative to Y specified by a predicate" ) {
846 auto PredY = [] (
Point p )
847 {
return ( -4 <= p.dot(
Point( 2,5 ) ) ) && ( p.dot(
Point( 2,5 ) ) < 9 ); };
849 THEN(
"It is fully convex and included in Y" ){
854 for (
auto p : FC_X_rel_Y )
856 nb_in += PredY( p ) ? 1 : 0;
864SCENARIO(
"DigitalConvexity< Z3 > relative envelope",
"[rel_envelope][3d]" )
872 DConvexity dconv(
Point( -360, -360, -360 ),
Point( 360, 360, 360 ) );
874 std::vector< Point > X {
Point( -61, -20, -8 ),
Point( 43, 25, 9 ) };
875 std::vector< Point > Y {
Point( -50, -27, -10 ),
Point( 40, 37, 17 ) };
876 std::sort( X.begin(), X.end() );
877 std::sort( Y.begin(), Y.end() );
882 WHEN(
"Computing the envelope of X relative to Y and Y relative to X" ) {
885 THEN(
"Both sets are fully convex" ){
889 THEN(
"There are inclusion rules between sets" ){
892 REQUIRE( std::includes( Y.cbegin(), Y.cend(),
893 FC_X_rel_Y.cbegin(), FC_X_rel_Y.cend() ) );
894 REQUIRE( std::includes( X.cbegin(), X.cend(),
895 FC_Y_rel_X.cbegin(), FC_Y_rel_X.cend() ) );
void getPoints(std::vector< Point > &pts) const
static PointRange insidePoints(const LatticePolytope &polytope)
static RationalPolytope makeRationalSimplex(Integer d, PointIterator itB, PointIterator itE)
bool isKConvex(const LatticePolytope &P, const Dimension k) const
static bool isSimplexFullDimensional(PointIterator itB, PointIterator itE)
static LatticePolytope makeSimplex(PointIterator itB, PointIterator itE)
bool isFullyConvexFast(const PointRange &X) const
bool isFullyConvex(const PointRange &X, bool convex0=false) const
PointRange envelope(const PointRange &Z, EnvelopeAlgorithm algo=EnvelopeAlgorithm::DIRECT) const
PointRange relativeEnvelope(const PointRange &Z, const PointRange &Y, EnvelopeAlgorithm algo=EnvelopeAlgorithm::DIRECT) const
bool isFullySubconvex(const PointRange &Y, const LatticeSet &StarX) const
LatticeSet StarCvxH(const PointRange &X, Dimension axis=dimension) const
Size depthLastEnvelope() const
LatticePolytope makePolytope(const PointRange &X, bool make_minkowski_summable=false) const
CellGeometry makeCellCover(PointIterator itB, PointIterator itE, Dimension i=0, Dimension k=KSpace::dimension) const
static SimplexType simplexType(PointIterator itB, PointIterator itE)
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
std::vector< Point > PointRange
DGtal is the top-level namespace which contains all DGtal functions and types.
GIVEN("A cubical complex with random 3-cells")
HyperRectDomain< Space > Domain
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")