35 #include "DGtal/base/Common.h"
36 #include "DGtal/arithmetic/LatticePolytope2D.h"
37 #include "DGtal/shapes/Shapes.h"
38 #include "DGtal/io/boards/Board2D.h"
43 using namespace DGtal;
49 template <
typename LatticePolytope2D>
58 typedef typename DigitalSet::ConstIterator ConstIterator;
61 #ifdef DEBUG_LatticePolytope2D
63 board <<
SetMode( d.className(),
"Grid" ) << d;
66 Color col1( 100, 100, 255 );
67 Color col2( 180, 180, 255 );
75 DigitalSet cipSet( d );
76 DigitalSet cipSet2( d );
80 #ifdef DEBUG_LatticePolytope2D
81 board <<
SetMode( d.className(),
"Grid" ) << d;
90 unsigned int nbok = 0;
92 for ( ConstIterator it = cipSet2.begin(), it_end = cipSet2.end();
95 nbok += ( cipSet.find( *it ) != cipSet.end() ) ? 1 : 0;
100 for ( ConstIterator it = cipSet.begin(), it_end = cipSet.end();
103 if ( cipSet2.find( *it ) == cipSet2.end() )
109 trace.
info() <<
"(" << nbok <<
"/" << nb <<
")"
110 <<
" cip.size()=" << cip.
size()
111 <<
" #before=" << cipSet.size()
112 <<
" #after=" << cipSet2.size()
122 template <
typename Space>
123 bool testLatticePolytope2D()
125 unsigned int nbok = 0;
128 trace.
beginBlock (
"Testing block LatticePolytope2D area and centroid" );
129 typedef typename Space::Point
Point;
130 typedef typename Space::Vector Vector;
131 typedef typename Space::Integer
Integer;
133 typedef typename CIP::Point3I Point3I;
134 typedef typename CIP::Domain Domain;
135 typedef typename CIP::HalfSpace HalfSpace;
136 typedef typename CIP::Iterator Iterator;
137 typedef typename CIP::SizeCouple SizeCouple;
142 cip.pushBack( Point( 5, 0 ) );
143 cip.pushBack( Point( 0, 3 ) );
144 Integer area2 = cip.twiceArea();
145 trace.
info() <<
"- 2*area = " << area2 << std::endl;
146 ++nb, nbok += ( area2 == 15 ) ? 1 : 0;
147 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
148 <<
"2*area == 15" << std::endl;
149 Point3I c = cip.centroid( area2 );
150 trace.
info() <<
"- centroid = " << c << std::endl;
151 ++nb, nbok += ( c == Point3I( 75, 45, 45 ) ) ? 1 : 0;
152 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
153 <<
"centroid == [75,45,45]" << std::endl;
154 Domain d = cip.boundingBoxDomain();
155 trace.
info() <<
"- domain = " << d << std::endl;
159 cip.pushBack( Point( -4, 4 ) );
160 cip.pushBack( Point( -7, 2 ) );
161 cip.pushBack( Point( -5, 1 ) );
163 d = cip.boundingBoxDomain();
164 board <<
SetMode( d.className(),
"Grid" ) << d;
165 DigitalSet aSet( d );
166 HalfSpace h( Vector( 1, 3 ), 8 );
169 Color col1( 100, 100, 255 );
170 Color col2( 180, 180, 255 );
173 cip.getIncludedDigitalPoints( aSet );
176 board <<
SetMode( cip.className(),
"Transparent" ) << cip;
178 SizeCouple nbs = cip.findCut( itA1, itB2, h );
179 Iterator itB1 = itA1; ++itB1;
180 if ( itB1 == cip.end() ) itB1 = cip.begin();
181 Iterator itA2 = itB2; ++itA2;
182 if ( itA2 == cip.end() ) itA2 = cip.begin();
183 Color col3( 0, 255, 0 );
184 Color col4( 255, 0, 0 );
195 board <<
SetMode( d.className(),
"Grid" ) << d;
196 board <<
SetMode( cip.className(),
"Transparent" ) << cip;
197 bool wasCut = cip.cut( h );
198 board <<
SetMode( cip.className(),
"Filled" ) << cip;
203 checkCut( cip, HalfSpace( Vector( -2, 3 ), 4 ) );
208 int myRandom(
int nb )
210 return random() % nb;
217 template <
typename Space>
218 bool exhaustiveTestLatticePolytope2D()
220 unsigned int nbok = 0;
223 trace.
beginBlock (
"Testing block LatticePolytope2D area and centroid" );
224 typedef typename Space::Point Point;
225 typedef typename Space::Vector Vector;
226 typedef typename Space::Integer Integer;
228 typedef typename CIP::Point3I Point3I;
229 typedef typename CIP::Domain Domain;
230 typedef typename CIP::HalfSpace HalfSpace;
231 typedef typename CIP::ConstIterator ConstIterator;
232 typedef typename CIP::SizeCouple SizeCouple;
236 cip.pushBack( Point( 0, 0 ) );
237 cip.pushBack( Point( 8, -3 ) );
238 cip.pushBack( Point( 17, 2 ) );
239 cip.pushBack( Point( 21, 13 ) );
240 cip.pushBack( Point( 13, 19 ) );
241 cip.pushBack( Point( 6, 17 ) );
242 cip.pushBack( Point( -3, 6 ) );
243 Integer area2 = cip.twiceArea();
244 trace.
info() <<
"- 2*area = " << area2 << std::endl;
245 Point3I c = cip.centroid( area2 );
246 trace.
info() <<
"- centroid = " << c << std::endl;
247 Domain d = cip.boundingBoxDomain();
248 trace.
info() <<
"- domain = " << d << std::endl;
252 for (
unsigned int j = 0; j < 100; ++j )
257 while ( ( x == 0 ) && ( y == 0 ) )
259 x = myRandom( 63 ) - 31;
260 y = myRandom( 63 ) - 31;
264 int c = myRandom( 4 ) *x + myRandom( 4 ) * y + myRandom( 40 ) + 40;
265 for (
unsigned int i = 0; i < 10; ++i, c -= myRandom( 40 ) )
267 HalfSpace h( Vector( x, y ), c );
268 trace.
info() <<
"[" << j <<
" size=" << cip2.size() <<
"]"
269 <<
" cut by (" << x <<
"," << y <<
")," << c << std::endl;
270 ++nb, nbok += checkCut( cip2, h ) ? 1 : 0;
271 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") cuts" << std::endl;
273 if ( nb != nbok )
break;
275 std::cerr << std::endl;
276 if ( nb != nbok )
break;
286 template <
typename Space>
287 bool specificTestLatticePolytope2D()
289 unsigned int nbok = 0;
292 typedef typename Space::Point Point;
293 typedef typename Space::Vector Vector;
294 typedef typename Space::Integer Integer;
296 typedef typename CIP::Point3I Point3I;
297 typedef typename CIP::Domain Domain;
298 typedef typename CIP::HalfSpace HalfSpace;
299 typedef typename CIP::Iterator Iterator;
300 typedef typename CIP::ConstIterator ConstIterator;
301 typedef typename CIP::SizeCouple SizeCouple;
305 cip.pushBack( Point( 0, 0 ) );
306 cip.pushBack( Point( 8, -3 ) );
307 cip.pushBack( Point( 17, 2 ) );
308 cip.pushBack( Point( 21, 13 ) );
309 cip.pushBack( Point( 13, 19 ) );
310 cip.pushBack( Point( 6, 17 ) );
311 cip.pushBack( Point( -3, 6 ) );
312 HalfSpace hs1( Vector( -5, 11 ), 8 );
313 HalfSpace hs2( Vector( -3, -11 ), 8 );
314 ++nb, nbok += checkCut( cip, hs1 ) ? 1 : 0;
316 Domain d = cip.boundingBoxDomain();
318 board <<
SetMode( d.className(),
"Grid" ) << d;
319 DigitalSet aSet( d );
320 ConstIterator itv = cip.begin();
321 ++itv; ++itv; ++itv; ++itv; ++itv; ++itv; ++itv;
322 HalfSpace hs( cip.halfSpace( itv ) );
324 Color col1( 100, 180, 100 );
325 Color col2( 130, 200, 130 );
328 board <<
SetMode( cip.className(),
"Transparent" ) << cip;
335 ++nb, nbok += checkCut( cip, hs2 ) ? 1 : 0;
339 template <
typename Space>
341 checkOutputConvexHullBorder()
343 typedef typename Space::Point Point;
344 typedef typename Space::Vector Vector;
345 typedef typename Space::Integer Integer;
347 typedef typename CIP::Point3I Point3I;
348 typedef typename CIP::Domain Domain;
349 typedef typename CIP::HalfSpace HalfSpace;
353 BOOST_CONCEPT_ASSERT(( boost::Container< CIP > ));
360 HalfSpace hs1( c1, c1 + Vector( 0, 1 ), In, ic );
361 HalfSpace hs2( A, B, In, ic );
362 HalfSpace hs3( c3, c3 + Vector( 0, 1 ), In, ic );
365 cip.computeConvexHullBorder( std::back_inserter( cip ), c1, c3, hs1, hs2, hs3 );
368 Domain d = cip.boundingBoxDomain();
370 board <<
SetMode( d.className(),
"Grid" ) << d;
371 DigitalSet aSet( d );
373 Color col1( 100, 180, 100 );
374 Color col2( 220, 250, 220 );
377 board <<
SetMode( cip.className(),
"Transparent" ) << cip;
389 int main(
int,
char** )
395 bool res = testLatticePolytope2D<Z2>()
396 && testLatticePolytope2D<Z2I>()
397 && exhaustiveTestLatticePolytope2D<Z2>()
398 && checkOutputConvexHullBorder<Z2>();
401 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;