DGtal 1.4.2
Loading...
Searching...
No Matches
testPConvexity.cpp
Go to the documentation of this file.
1
31#include <iostream>
32#include <vector>
33#include <algorithm>
34#include "DGtal/base/Common.h"
35#include "DGtal/kernel/SpaceND.h"
36#include "DGtal/kernel/domains/HyperRectDomain.h"
37#include "DGtal/kernel/sets/DigitalSetBySTLSet.h"
38#include "DGtal/topology/KhalimskySpaceND.h"
39#include "DGtal/shapes/Shapes.h"
40#include "DGtal/geometry/volumes/PConvexity.h"
41#include "DGtal/geometry/volumes/DigitalConvexity.h"
42#include "DGtalCatch.h"
44
45using namespace std;
46using namespace DGtal;
47
48
50// Functions for testing class PConvexity.
52
53SCENARIO( "PConvexity< Z2 > P-convexity tests", "[p_convexity][2d]" )
54{
56 typedef Space::Point Point;
57 typedef PConvexity< Space > Convexity;
58
59 Convexity pconv;
60
61 std::vector<Point> V1 = { Point(0,0), Point(-1,0), Point(1,0), Point(0,1) };
62 REQUIRE( pconv.is0Convex( V1 ) );
63 REQUIRE( pconv.isPConvex( V1 ) );
64 REQUIRE( pconv.convexityMeasure( V1 ) == 1.0 );
65 REQUIRE( pconv.fullConvexityMeasure( V1 ) == 1.0 );
66 std::vector<Point> V2 = { Point(-1,0), Point(1,0), Point(0,1) };
67 REQUIRE( ! pconv.is0Convex( V2 ) );
68 REQUIRE( ! pconv.isPConvex( V2 ) );
69 REQUIRE( pconv.convexityMeasure( V2 ) < 1.0 );
70 REQUIRE( pconv.fullConvexityMeasure( V2 ) < 1.0 );
71 std::vector<Point> V3 = { Point(0,0), Point(-1,0), Point(1,0) };
72 REQUIRE( pconv.is0Convex( V3 ) );
73 REQUIRE( pconv.isPConvex( V3 ) );
74 REQUIRE( pconv.convexityMeasure( V3 ) == 1.0 );
75 REQUIRE( pconv.fullConvexityMeasure( V3 ) == 1.0 );
76 std::vector<Point> V4 = { Point(0,0), Point(-1,0), Point(1,0), Point(0,1),
77 Point(0,-1) };
78 REQUIRE( pconv.is0Convex( V4 ) );
79 REQUIRE( pconv.isPConvex( V4 ) );
80 std::vector<Point> V5 = { Point(-1,0), Point(0,0), Point(3,1) };
81 REQUIRE( pconv.is0Convex( V5 ) );
82 REQUIRE( ! pconv.isPConvex( V5 ) );
83 REQUIRE( pconv.convexityMeasure( V5 ) == 1.0 );
84 REQUIRE( pconv.fullConvexityMeasure( V5 ) < 1.0 );
85}
86
87SCENARIO( "PConvexity< Z3 > ball tests", "[p_convexity][3d]" )
88{
89 GIVEN( "Given a 3D digital ball of radius 5 " ) {
90 typedef SpaceND<3,int> Space;
91 typedef Space::Point Point;
92 typedef PConvexity< Space > Convexity;
95
96 Convexity pconv;
97 Point lo = Point::diagonal( -7 );
98 Point hi = Point::diagonal( 7 );
99 Point c = Point::zero;
100 Domain domain( lo, hi );
101 DigitalSet ball ( domain );
102 Shapes< Domain >::addNorm2Ball( ball, c, 5 );
103 std::vector<Point> V( ball.begin(), ball.end() );
104 bool cvx0 = pconv.is0Convex( V );
105 bool fcvx = pconv.isPConvex( V );
106 THEN( "It is a 0-convex and P-convex by morphological characterization" ) {
107 REQUIRE( cvx0 );
108 REQUIRE( fcvx );
109 }
110 THEN( "Then both its convexity measure and its full convexity measure is 1.0" ) {
111 REQUIRE( pconv.convexityMeasure( V ) == 1.0 );
112 REQUIRE( pconv.fullConvexityMeasure( V ) == 1.0 );
113 }
114 }
115}
116
117SCENARIO( "PConvexity< Z4 > ball tests", "[p_convexity][4d]" )
118{
119 GIVEN( "Given a 4D digital ball of radius 5 " ) {
120 typedef SpaceND<4,int> Space;
121 typedef Space::Point Point;
122 typedef PConvexity< Space > Convexity;
125
126 Convexity conv;
127 Point lo = Point::diagonal( -7 );
128 Point hi = Point::diagonal( 7 );
129 Point c = Point::zero;
130 Domain domain( lo, hi );
131 DigitalSet ball ( domain );
132 Shapes< Domain >::addNorm2Ball( ball, c, 5 );
133 std::vector<Point> V( ball.begin(), ball.end() );
134 bool cvx0 = conv.is0Convex( V );
135 bool fcvx = conv.isPConvex( V );
136 THEN( "It is a 0-convex and P-convex by morphological characterization" ) {
137 REQUIRE( cvx0 );
138 REQUIRE( fcvx );
139 }
140 THEN( "Then both its convexity measure and its full convexity measure is 1.0" ) {
141 REQUIRE( conv.convexityMeasure( V ) == 1.0 );
142 REQUIRE( conv.fullConvexityMeasure( V ) == 1.0 );
143 }
144 }
145}
146
147
148SCENARIO( "DigitalConvexity< Z3 > fully convex and p-convex tetrahedra", "[p_convexity][full_convexity][convex_simplices][3d]" )
149{
151 typedef KSpace::Point Point;
152 typedef KSpace::Space Space;
154 typedef DigitalConvexity< KSpace > DConvexity;
156
157 Domain domain( Point( 0, 0, 0 ), Point( 3, 3, 3 ) );
158 DConvexity dconv( Point( -1, -1, -1 ), Point( 4, 4, 4 ) );
159 PConvexity pconv;
160
161 WHEN( "Computing many tetrahedra in domain (0,0,0)-(4,4,4)." ) {
162 const unsigned int nb = 100;
163 unsigned int nbsimplex= 0;
164 unsigned int nb0 = 0;
165 unsigned int nb1 = 0;
166 unsigned int nb2 = 0;
167 unsigned int nb3 = 0;
168 unsigned int nb012_not3 = 0;
169 unsigned int nbf = 0;
170 unsigned int nbfg = 0;
171 unsigned int nbffast = 0;
172 unsigned int nbp = 0;
173 unsigned int nb0123 = 0;
174 for ( unsigned int i = 0; i < nb; ++i )
175 {
176 Point a( rand() % 5, rand() % 5, rand() % 5 );
177 Point b( rand() % 5, rand() % 5, rand() % 5 );
178 Point c( rand() % 5, rand() % 5, rand() % 5 );
179 Point d( rand() % 5, rand() % 5, rand() % 5 );
180 if ( ! dconv.isSimplexFullDimensional( { a, b, c, d } ) ) continue;
181 auto tetra = dconv.makeSimplex( { a, b, c, d } );
182 std::vector< Point > X;
183 tetra.getPoints( X );
184 bool cvx0 = dconv.isKConvex( tetra, 0 );
185 bool cvx1 = dconv.isKConvex( tetra, 1 );
186 bool cvx2 = dconv.isKConvex( tetra, 2 );
187 bool cvx3 = dconv.isKConvex( tetra, 3 );
188 bool cvxf = dconv.isFullyConvex( tetra );
189 bool cvxfg = dconv.isFullyConvex( X, false );
190 bool cvxffast = dconv.isFullyConvexFast( X );
191 bool cvxp = pconv.isPConvex( X );
192 if ( cvxf != cvxfg || cvxf != cvxffast || cvxf != cvxp ) {
193 std::cout << "[" << cvx0 << cvx1 << cvx2 << cvx3 << "] "
194 << "[" << cvxf << "] [" << cvxfg
195 << "] [" << cvxffast << "]"
196 << "] [" << cvxp << "]"
197 << a << b << c << d << std::endl;
198 }
199 nbsimplex += 1;
200 nb0 += cvx0 ? 1 : 0;
201 nb1 += cvx1 ? 1 : 0;
202 nb2 += cvx2 ? 1 : 0;
203 nb3 += cvx3 ? 1 : 0;
204 nbf += cvxf ? 1 : 0;
205 nbfg += cvxfg ? 1 : 0;
206 nbffast += cvxffast ? 1 : 0;
207 nbp += cvxp ? 1 : 0;
208 nb0123 += ( cvx0 && cvx1 && cvx2 && cvx3 ) ? 1 : 0;
209 nb012_not3+= ( cvx0 && cvx1 && cvx2 && ! cvx3 ) ? 1 : 0;
210 }
211 THEN( "All valid tetrahedra are 0-convex." ) {
212 REQUIRE( nb0 == nbsimplex );
213 }
214 THEN( "There are less 1-convex, 2-convex and 3-convex than 0-convex." ) {
215 REQUIRE( nb1 < nb0 );
216 REQUIRE( nb2 < nb0 );
217 REQUIRE( nb3 < nb0 );
218 }
219 THEN( "When the tetrahedron is 0-convex, 1-convex and 2-convex, then it is 3-convex, so fully convex and also P-convex." ) {
220 REQUIRE( nb1 <= nb3 );
221 REQUIRE( nb2 <= nb3 );
222 REQUIRE( nb012_not3 == 0 );
223 REQUIRE( nbf == nb0123 );
224 REQUIRE( nbf == nbp );
225 }
226 THEN( "All methods for computing full convexity and P-convexity agree." ) {
227 REQUIRE( nbf == nbfg );
228 REQUIRE( nbf == nbffast );
229 REQUIRE( nbf == nbp );
230 }
231 }
232}
233
void getPoints(std::vector< Point > &pts) const
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
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: A container class for storing sets of digital points within some given domain.
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
Aim: A class to check if digital sets are P-convex. The P-convexity is defined as follows: A digital ...
Definition PConvexity.h:355
bool isPConvex(const std::vector< Point > &X) const
Definition PConvexity.h:407
static void addNorm2Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)
DGtal is the top-level namespace which contains all DGtal functions and types.
STL namespace.
MyPointD Point
GIVEN("A cubical complex with random 3-cells")
Domain domain
HyperRectDomain< Space > Domain
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")
Z2i::DigitalSet DigitalSet