34 #include "DGtal/base/Common.h"
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/geometry/tools/QuickHull.h"
37 #include "DGtalCatch.h"
41 using namespace DGtal;
43 template <
typename Po
int>
47 std::vector< Point > V;
48 Point c = Point::diagonal( R );
49 double R2 = (double) R * (
double) R;
50 for (
int i = 0; i < nb; ) {
53 p[ k ] = rand() % (2*R);
54 if ( ( p - c ).squaredNorm() < R2 ) { V.push_back( p ); i++; }
63 SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 2 > > unit tests",
"[quickhull][integral_kernel][2d]" )
70 typedef QHull::IndexRange IndexRange;
73 GIVEN(
"Given a star { (0,0), (-4,-1), (-3,5), (7,3), (5, -2) } " ) {
77 hull.setInput( V,
false );
78 hull.computeConvexHull();
79 THEN(
"The convex hull is valid and contains every point" ) {
82 THEN(
"Its convex hull has 4 vertices" ) {
83 REQUIRE( hull.nbVertices() == 4 );
85 THEN(
"Its convex hull has 4 facets" ) {
86 REQUIRE( hull.nbFacets() == 4 );
88 THEN(
"Its facets form a linked list" ) {
89 std::vector< IndexRange > facets;
90 hull.getFacetVertices( facets );
91 std::vector< Index > next( hull.nbVertices(), (
Index) -1 );
92 Index nb_zero_next = hull.nbVertices();
93 Index nb_two_next = 0;
94 for (
auto f : facets ) {
95 if ( next[ f[ 0 ] ] != (
Index) -1 ) nb_two_next += 1;
97 next[ f[ 0 ] ] = f[ 1 ];
105 GIVEN(
"Given 100 random point in a ball of radius 50 " ) {
106 std::vector<Point> V = randomPointsInBall< Point >( 100, 50 );
108 hull.setInput( V,
false );
109 hull.computeConvexHull();
110 THEN(
"The convex hull is valid and contains every point" ) {
113 THEN(
"Its convex hull has the same number of vertices and facets" ) {
114 REQUIRE( hull.nbVertices() == hull.nbFacets() );
116 THEN(
"Its convex hull has much fewer vertices than input points" ) {
117 REQUIRE( 2*hull.nbVertices() <= hull.nbPoints() );
119 THEN(
"Its facets form a linked list" ) {
120 std::vector< IndexRange > facets;
121 hull.getFacetVertices( facets );
122 std::vector< Index > next( hull.nbVertices(), (
Index) -1 );
123 Index nb_zero_next = hull.nbVertices();
124 Index nb_two_next = 0;
125 for (
auto f : facets ) {
126 if ( next[ f[ 0 ] ] != (
Index) -1 ) nb_two_next += 1;
128 next[ f[ 0 ] ] = f[ 1 ];
143 SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 3 > > unit tests",
"[quickhull][integral_kernel][3d]" )
149 typedef QHull::IndexRange IndexRange;
152 GIVEN(
"Given an octahedron" ) {
154 std::vector<Point> V = {
Point( 0,0,0 ) };
156 V.push_back( Point::base( k, R ) );
157 V.push_back( Point::base( k, -R ) );
160 hull.setInput( V,
false );
161 hull.setInitialSimplex( IndexRange { 0, 1, 3, 5 } );
162 hull.computeConvexHull();
163 THEN(
"The convex hull is valid and contains every point" ) {
166 THEN(
"Its convex hull has 6 vertices" ) {
167 REQUIRE( hull.nbVertices() == 6 );
169 THEN(
"Its convex hull has 8 facets" ) {
170 REQUIRE( hull.nbFacets() == 8 );
173 GIVEN(
"Given 100 random point in a ball of radius 50 " ) {
174 std::vector<Point> V = randomPointsInBall< Point >( 100, 50 );
176 hull.setInput( V,
false );
177 hull.computeConvexHull();
178 THEN(
"The convex hull is valid and contains every point" ) {
181 THEN(
"Its convex hull has more facets than vertices" ) {
182 REQUIRE( hull.nbVertices() < hull.nbFacets() );
184 THEN(
"Its convex hull has fewer vertices than input points" ) {
185 REQUIRE( hull.nbVertices() < hull.nbPoints() );
195 SCENARIO(
"QuickHull< ConvexHullIntegralKernel< 4 > > unit tests",
"[quickhull][integral_kernel][4d]" )
203 GIVEN(
"Given an octahedron" ) {
205 std::vector<Point> V = {
Point( 0,0,0,0 ) };
207 V.push_back( Point::base( k, R ) );
208 V.push_back( Point::base( k, -R ) );
211 hull.setInput( V,
false );
212 hull.computeConvexHull();
213 THEN(
"The convex hull is valid and contains every point" ) {
216 THEN(
"Its convex hull has 8 vertices" ) {
217 REQUIRE( hull.nbVertices() == 8 );
219 THEN(
"Its convex hull has 16 facets" ) {
220 REQUIRE( hull.nbFacets() == 16 );
223 GIVEN(
"Given 100 random point in a ball of radius 50 " ) {
224 std::vector<Point> V = randomPointsInBall< Point >( 100, 50 );
226 hull.setInput( V,
false );
227 hull.computeConvexHull();
228 THEN(
"The convex hull is valid and contains every point" ) {
231 THEN(
"Its convex hull has fewer vertices than input points" ) {
232 REQUIRE( hull.nbVertices() < hull.nbPoints() );
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::uint32_t Dimension
Aim: a geometric kernel to compute the convex hull of digital points with integer-only arithmetic.
Aim: Implements the quickhull algorithm by Barber et al. , a famous arbitrary dimensional convex hull...
GIVEN("A cubical complex with random 3-cells")
std::vector< Point > randomPointsInBall(int nb, int R)
SCENARIO("QuickHull< ConvexHullIntegralKernel< 2 > > unit tests", "[quickhull][integral_kernel][2d]")
REQUIRE(domain.isInside(aPoint))