93SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 2 > > unit tests",
"[quickhull][integral_kernel][2d]" )
98 typedef Space::Point
Point;
99 typedef QHull::Index
Index;
100 typedef QHull::IndexRange IndexRange;
103 GIVEN(
"Given a star { (0,0), (-4,-1), (-3,5), (7,3), (5, -2) } " ) {
107 hull.setInput( V,
false );
108 hull.computeConvexHull();
109 THEN(
"The convex hull is valid and contains every point" ) {
112 THEN(
"Its convex hull has 4 vertices" ) {
113 REQUIRE( hull.nbVertices() == 4 );
115 THEN(
"Its convex hull has 4 facets" ) {
116 REQUIRE( hull.nbFacets() == 4 );
118 THEN(
"Its facets form a linked list" ) {
119 std::vector< IndexRange > facets;
120 hull.getFacetVertices( facets );
121 std::vector< Index > next( hull.nbVertices(), (
Index) -1 );
122 Index nb_zero_next = hull.nbVertices();
123 Index nb_two_next = 0;
124 for (
auto f : facets ) {
125 if ( next[ f[ 0 ] ] != (
Index) -1 ) nb_two_next += 1;
127 next[ f[ 0 ] ] = f[ 1 ];
135 GIVEN(
"Given 100 random point in a ball of radius 50 " ) {
136 std::vector<Point> V = randomPointsInBall< Point >( 100, 50 );
138 hull.setInput( V,
false );
139 hull.computeConvexHull();
140 THEN(
"The convex hull is valid and contains every point" ) {
143 THEN(
"Its convex hull has the same number of vertices and facets" ) {
144 REQUIRE( hull.nbVertices() == hull.nbFacets() );
146 THEN(
"Its convex hull has much fewer vertices than input points" ) {
147 REQUIRE( 2*hull.nbVertices() <= hull.nbPoints() );
149 THEN(
"Its facets form a linked list" ) {
150 std::vector< IndexRange > facets;
151 hull.getFacetVertices( facets );
152 std::vector< Index > next( hull.nbVertices(), (
Index) -1 );
153 Index nb_zero_next = hull.nbVertices();
154 Index nb_two_next = 0;
155 for (
auto f : facets ) {
156 if ( next[ f[ 0 ] ] != (
Index) -1 ) nb_two_next += 1;
158 next[ f[ 0 ] ] = f[ 1 ];
168SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 2 > > dimensionality tests",
"[quickhull][integral_kernel][2d][not_full_dimensional]" )
173 typedef Space::Point
Point;
176 std::vector< Point > V = {
Point{ 3, 1 } };
178 GIVEN(
"Given 100 aligned points" ) {
180 auto I = Affine::affineSubset( X );
181 auto d = Affine::affineDimension( X );
183 hull.setInput( X,
false );
184 bool ok = hull.computeConvexHull();
185 auto status = hull.status();
186 THEN(
"AffineSubset should detect not full dimensionality" ) {
190 THEN(
"QuickHull should detect not full dimensionality" ) {
192 REQUIRE( status == QHull::Status::NotFullDimensional );
196 GIVEN(
"Given 100 aligned points + another not aligned" ) {
198 X.push_back( X[ 0 ] +
Point(-1,1) );
199 std::shuffle( X.begin(), X.end(),
g );
200 auto I = Affine::affineSubset( X );
201 auto d = Affine::affineDimension( X );
203 hull.setInput( X,
false );
204 bool ok = hull.computeConvexHull();
205 auto status = hull.status();
206 THEN(
"AffineSubset should detect full dimensionality" ) {
210 THEN(
"QuickHull should detect full dimensionality" ) {
212 REQUIRE( status != QHull::Status::NotFullDimensional );
214 THEN(
"QuickHull should find 3 vertices" ) {
215 REQUIRE( hull.nbVertices() == 3 );
224SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 3 > > unit tests",
"[quickhull][integral_kernel][3d]" )
229 typedef Space::Point
Point;
230 typedef QHull::IndexRange IndexRange;
233 GIVEN(
"Given an octahedron" ) {
235 std::vector<Point> V = {
Point( 0,0,0 ) };
237 V.push_back( Point::base( k,
R ) );
238 V.push_back( Point::base( k, -
R ) );
241 hull.setInput( V,
false );
242 hull.setInitialSimplex( IndexRange { 0, 1, 3, 5 } );
243 hull.computeConvexHull();
244 THEN(
"The convex hull is valid and contains every point" ) {
247 THEN(
"Its convex hull has 6 vertices" ) {
248 REQUIRE( hull.nbVertices() == 6 );
250 THEN(
"Its convex hull has 8 facets" ) {
251 REQUIRE( hull.nbFacets() == 8 );
254 GIVEN(
"Given 100 random point in a ball of radius 50 " ) {
255 std::vector<Point> V = randomPointsInBall< Point >( 100, 50 );
257 hull.setInput( V,
false );
258 hull.computeConvexHull();
259 THEN(
"The convex hull is valid and contains every point" ) {
262 THEN(
"Its convex hull has more facets than vertices" ) {
263 REQUIRE( hull.nbVertices() < hull.nbFacets() );
265 THEN(
"Its convex hull has fewer vertices than input points" ) {
266 REQUIRE( hull.nbVertices() < hull.nbPoints() );
271SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 3 > > dimensionality tests",
"[quickhull][integral_kernel][3d][not_full_dimensional]" )
276 typedef Space::Point
Point;
279 GIVEN(
"Given 100 aligned points" ) {
280 std::vector< Point > V = {
Point{ 3, 1, -1 } };
282 auto I = Affine::affineSubset( X );
283 auto d = Affine::affineDimension( X );
285 hull.setInput( X,
false );
286 bool ok = hull.computeConvexHull();
287 auto status = hull.status();
288 THEN(
"AffineSubset should detect not full dimensionality" ) {
292 THEN(
"QuickHull should detect not full dimensionality" ) {
294 REQUIRE( status == QHull::Status::NotFullDimensional );
298 GIVEN(
"Given 100 aligned points + another not aligned" ) {
299 std::vector< Point > V = {
Point{ 3, 2, -1 } };
301 X.push_back( X[ 0 ] +
Point(-1,1,-1) );
302 std::shuffle( X.begin(), X.end(),
g );
303 auto I = Affine::affineSubset( X );
304 auto d = Affine::affineDimension( X );
306 hull.setInput( X,
false );
307 bool ok = hull.computeConvexHull();
308 auto status = hull.status();
309 THEN(
"AffineSubset should detect not full dimensionality (dimension 2)" ) {
313 THEN(
"QuickHull should detect not full dimensionality" ) {
315 REQUIRE( status == QHull::Status::NotFullDimensional );
319 GIVEN(
"Given 100 points on a lattice plane" ) {
320 std::vector< Point > V = {
Point{ 3, 1, -1 },
Point{ -2, 2, 1 } };
322 auto I = Affine::affineSubset( X );
323 auto d = Affine::affineDimension( X );
325 hull.setInput( X,
false );
326 bool ok = hull.computeConvexHull();
327 auto status = hull.status();
328 THEN(
"AffineSubset should detect not full dimensionality (dimension 2)" ) {
332 THEN(
"QuickHull should detect not full dimensionality" ) {
334 REQUIRE( status == QHull::Status::NotFullDimensional );
338 GIVEN(
"Given 100 points on a lattice plane + a point just outside" ) {
339 std::vector< Point > V = {
Point{ 3, 1, -1 },
Point{ -2, 2, 1 } };
341 X.push_back( X[ 0 ] +
Point(-1,1,-1) );
342 std::shuffle( X.begin(), X.end(),
g );
343 auto I = Affine::affineSubset( X );
344 auto d = Affine::affineDimension( X );
346 hull.setInput( X,
false );
347 bool ok = hull.computeConvexHull();
348 auto status = hull.status();
349 THEN(
"AffineSubset should detect full dimensionality" ) {
353 THEN(
"QuickHull should detect full dimensionality" ) {
355 REQUIRE( status != QHull::Status::NotFullDimensional );
357 THEN(
"QuickHull should have more than 3 vertices" ) {
358 REQUIRE( hull.nbVertices() > 3 );
369SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 4 > > unit tests",
"[quickhull][integral_kernel][4d]" )
374 typedef Space::Point
Point;
377 GIVEN(
"Given an octahedron" ) {
379 std::vector<Point> V = {
Point( 0,0,0,0 ) };
381 V.push_back( Point::base( k,
R ) );
382 V.push_back( Point::base( k, -
R ) );
385 hull.setInput( V,
false );
386 hull.computeConvexHull();
387 THEN(
"The convex hull is valid and contains every point" ) {
390 THEN(
"Its convex hull has 8 vertices" ) {
391 REQUIRE( hull.nbVertices() == 8 );
393 THEN(
"Its convex hull has 16 facets" ) {
394 REQUIRE( hull.nbFacets() == 16 );
397 GIVEN(
"Given 100 random point in a ball of radius 50 " ) {
398 std::vector<Point> V = randomPointsInBall< Point >( 100, 50 );
400 hull.setInput( V,
false );
401 hull.computeConvexHull();
402 THEN(
"The convex hull is valid and contains every point" ) {
405 THEN(
"Its convex hull has fewer vertices than input points" ) {
406 REQUIRE( hull.nbVertices() < hull.nbPoints() );
411SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 4 > > dimensionality tests",
"[quickhull][integral_kernel][4d][not_full_dimensional]" )
416 typedef Space::Point
Point;
419 GIVEN(
"Given 100 aligned points" ) {
420 std::vector< Point > V = {
Point{ 3, 1, -1, 2 } };
422 auto I = Affine::affineSubset( X );
423 auto d = Affine::affineDimension( X );
425 hull.setInput( X,
false );
426 bool ok = hull.computeConvexHull();
427 auto status = hull.status();
428 THEN(
"AffineSubset should detect not full dimensionality" ) {
432 THEN(
"QuickHull should detect not full dimensionality" ) {
434 REQUIRE( status == QHull::Status::NotFullDimensional );
438 GIVEN(
"Given 100 aligned points + another not aligned" ) {
439 std::vector< Point > V = {
Point{ 3, 2, -1, 2 } };
441 X.push_back( X[ 0 ] +
Point(-1,1,-1,0) );
442 std::shuffle( X.begin(), X.end(),
g );
443 auto I = Affine::affineSubset( X );
444 auto d = Affine::affineDimension( X );
446 hull.setInput( X,
false );
447 bool ok = hull.computeConvexHull();
448 auto status = hull.status();
449 THEN(
"AffineSubset should detect not full dimensionality (dimension 2)" ) {
453 THEN(
"QuickHull should detect not full dimensionality" ) {
455 REQUIRE( status == QHull::Status::NotFullDimensional );
459 GIVEN(
"Given 100 points on a lattice 2d plane" ) {
460 std::vector< Point > V = {
Point{ 3, 1, -1, 2 },
Point{ -2, 2, 1, -1 } };
462 auto I = Affine::affineSubset( X );
463 auto d = Affine::affineDimension( X );
465 hull.setInput( X,
false );
466 bool ok = hull.computeConvexHull();
467 auto status = hull.status();
468 THEN(
"AffineSubset should detect not full dimensionality (dimension 2)" ) {
472 THEN(
"QuickHull should detect not full dimensionality" ) {
474 REQUIRE( status == QHull::Status::NotFullDimensional );
478 GIVEN(
"Given 100 points on a lattice plane + a point just outside" ) {
479 std::vector< Point > V = {
Point{ 3, 1, -1, 2 },
Point{ -2, 2, 1, -1 } };
481 X.push_back( X[ 0 ] +
Point(-1,1,-1,0) );
482 std::shuffle( X.begin(), X.end(),
g );
483 auto I = Affine::affineSubset( X );
484 auto d = Affine::affineDimension( X );
486 hull.setInput( X,
false );
487 bool ok = hull.computeConvexHull();
488 auto status = hull.status();
489 THEN(
"AffineSubset should detect not full dimensionality (dimension 3)" ) {
493 THEN(
"QuickHull should detect not full dimensionality" ) {
495 REQUIRE( status == QHull::Status::NotFullDimensional );
499 GIVEN(
"Given 100 points on a lattice 3d plane" ) {
500 std::vector< Point > V = {
Point{ 3, 1, -1, 2 },
Point{ -2, 2, 1, -1 },
Point{ 0, -3, -2, 2 } };
502 auto I = Affine::affineSubset( X );
503 auto d = Affine::affineDimension( X );
505 hull.setInput( X,
false );
506 bool ok = hull.computeConvexHull();
507 auto status = hull.status();
508 THEN(
"AffineSubset should detect not full dimensionality (dimension 3)" ) {
512 THEN(
"QuickHull should detect not full dimensionality" ) {
514 REQUIRE( status == QHull::Status::NotFullDimensional );
518 GIVEN(
"Given 100 points on a lattice 3d plane + one exterior point" ) {
519 std::vector< Point > V = {
Point{ 3, 1, -1, 2 },
Point{ -2, 2, 1, -1 },
Point{ 0, -3, -2, 2 } };
521 X.push_back( X[ 0 ] +
Point(-1,1,-1,0) );
522 std::shuffle( X.begin(), X.end(),
g );
523 auto I = Affine::affineSubset( X );
524 auto d = Affine::affineDimension( X );
526 hull.setInput( X,
false );
527 bool ok = hull.computeConvexHull();
528 auto status = hull.status();
529 THEN(
"AffineSubset should detect full dimensionality" ) {
533 THEN(
"QuickHull should detect full dimensionality" ) {
535 REQUIRE( status != QHull::Status::NotFullDimensional );
537 THEN(
"QuickHull should have more than 4 vertices" ) {
538 REQUIRE( hull.nbVertices() > 4 );
540 THEN(
"QuickHull should have more than 4 facets" ) {
541 REQUIRE( hull.nbFacets() > 4 );