33 #include "DGtal/base/Common.h"
34 #include "DGtal/helpers/StdDefs.h"
35 #include "DGtal/kernel/CPointPredicate.h"
36 #include "DGtal/geometry/surfaces/CAdditivePrimitiveComputer.h"
37 #include "DGtal/geometry/surfaces/ChordNaivePlaneComputer.h"
38 #include "DGtal/geometry/surfaces/ChordGenericNaivePlaneComputer.h"
42 using namespace DGtal;
49 template <
typename Integer>
53 return ( r % (after_last - first) ) + first;
59 template <
typename Integer,
typename NaivePlaneComputer>
62 int diameter,
unsigned int nbtries )
65 typedef typename Point::Component PointInteger;
72 if ( ( absA >= absB ) && ( absA >= absC ) )
74 else if ( ( absB >= absA ) && ( absB >= absC ) )
80 plane.
init( axis, 1, 1 );
83 unsigned int nbok = 0;
84 while ( nb != nbtries )
86 p[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
87 p[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
88 p[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
98 bool ok = plane.
extend( p );
99 ++nb; nbok += ok_ext ? 1 : 0;
100 ++nb; nbok += ok ? 1 : 0;
103 std::cerr <<
"[ERROR] p=" << p <<
" NOT IN plane=" << plane << std::endl;
106 std::cerr <<
" " << *it;
108 std::cerr <<
"d <= a*x+b*y+c*z <= d+max(a,b,c)"
109 << d <<
" <= " << a <<
"*" << p[0]
110 <<
"+" << b <<
"*" << p[1]
111 <<
"+" << c <<
"*" << p[2]
112 <<
" = " << (a*p[0]+b*p[1]+c*p[2])
118 std::cerr <<
"[ERROR] p=" << p <<
" was NOT extendable IN plane=" << plane << std::endl;
126 while ( nb != (nbtries * 11 ) / 10 )
128 p[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
129 p[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
130 p[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
139 PointInteger tmp = getRandomInteger<PointInteger>( 2, 5 )
140 * (2*getRandomInteger<PointInteger>( 0, 2 ) - 1 );
143 bool ok = ! plane.
extend( p );
144 ++nb; nbok += ok ? 1 : 0;
145 ++nb; nbok += ok_ext ? 1 : 0;
148 std::cerr <<
"[ERROR] p=" << p <<
" IN plane=" << plane << std::endl;
153 std::cerr <<
"[ERROR] p=" << p <<
" was extendable IN plane=" << plane << std::endl;
165 template <
typename Integer,
typename NaivePlaneComputer>
168 int diameter,
unsigned int nbtries )
171 typedef typename Point::Component PointInteger;
178 if ( ( absA >= absB ) && ( absA >= absC ) )
180 else if ( ( absB >= absA ) && ( absB >= absC ) )
186 plane.
init( axis, 1, 1 );
189 unsigned int nbok = 0;
190 while ( nb < nbtries )
192 std::vector<Point> points( 5 );
193 for (
unsigned int i = 0; i < 5; ++i )
195 Point & pp = points[ i ];
196 pp[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
197 pp[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
198 pp[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
204 ( ic.
ceilDiv( d - b * y - c * z, a ) );
break;
206 ( ic.
ceilDiv( d - a * x - c * z, b ) );
break;
208 ( ic.
ceilDiv( d - a * x - b * y, c ) );
break;
211 bool ok_ext = plane.
isExtendable( points.begin(), points.end() );
212 bool ok = plane.
extend( points.begin(), points.end() );
213 ++nb; nbok += ok_ext ? 1 : 0;
214 ++nb; nbok += ok ? 1 : 0;
217 std::cerr <<
"[ERROR] p=" << points[ 0 ] <<
" NOT IN plane=" << plane << std::endl;
220 std::cerr <<
" " << *it;
222 std::cerr <<
"d <= a*x+b*y+c*z <= d+max(a,b,c)"
223 << d <<
" <= " << a <<
"*" << p[0]
224 <<
"+" << b <<
"*" << p[1]
225 <<
"+" << c <<
"*" << p[2]
226 <<
" = " << (a*p[0]+b*p[1]+c*p[2])
232 std::cerr <<
"[ERROR] p=" << p <<
" was NOT extendable IN plane=" << plane << std::endl;
240 while ( nb < (nbtries * 11 ) / 10 )
242 p[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
243 p[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
244 p[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
253 PointInteger tmp = getRandomInteger<PointInteger>( 2, 5 )
254 * (2*getRandomInteger<PointInteger>( 0, 2 ) - 1 );
257 bool ok = ! plane.
extend( p );
258 ++nb; nbok += ok ? 1 : 0;
259 ++nb; nbok += ok_ext ? 1 : 0;
262 std::cerr <<
"[ERROR] p=" << p <<
" IN plane=" << plane << std::endl;
267 std::cerr <<
"[ERROR] p=" << p <<
" was extendable IN plane=" << plane << std::endl;
281 template <
typename Integer,
typename GenericNaivePlaneComputer>
284 int diameter,
unsigned int nbtries )
287 typedef typename Point::Component PointInteger;
294 if ( ( absA >= absB ) && ( absA >= absC ) )
296 else if ( ( absB >= absA ) && ( absB >= absC ) )
301 GenericNaivePlaneComputer plane;
305 unsigned int nbok = 0;
306 while ( nb != nbtries )
308 p[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
309 p[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
310 p[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
319 bool ok_ext = plane.isExtendable( p );
320 bool ok = plane.extend( p );
321 ++nb; nbok += ok_ext ? 1 : 0;
322 ++nb; nbok += ok ? 1 : 0;
325 std::cerr <<
"[ERROR] p=" << p <<
" NOT IN plane=" << plane << std::endl;
328 std::cerr <<
" " << *it;
330 std::cerr <<
"d <= a*x+b*y+c*z <= d+max(a,b,c)"
331 << d <<
" <= " << a <<
"*" << p[0]
332 <<
"+" << b <<
"*" << p[1]
333 <<
"+" << c <<
"*" << p[2]
334 <<
" = " << (a*p[0]+b*p[1]+c*p[2])
340 std::cerr <<
"[ERROR] p=" << p <<
" was NOT extendable IN plane=" << plane << std::endl;
348 while ( nb != (nbtries * 11 ) / 10 )
350 p[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
351 p[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
352 p[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
361 PointInteger tmp = getRandomInteger<PointInteger>( 2, 5 )
362 * (2*getRandomInteger<PointInteger>( 0, 2 ) - 1 );
364 bool ok_ext = ! plane.isExtendable( p );
365 bool ok = ! plane.extend( p );
366 ++nb; nbok += ok ? 1 : 0;
367 ++nb; nbok += ok_ext ? 1 : 0;
370 std::cerr <<
"[ERROR] p=" << p <<
" IN plane=" << plane << std::endl;
375 std::cerr <<
"[ERROR] p=" << p <<
" was extendable IN plane=" << plane << std::endl;
381 std::cerr <<
"plane = " << plane << std::endl;
386 template <
typename Integer,
typename NaivePlaneComputer>
388 checkPlanes(
unsigned int nbplanes,
int diameter,
unsigned int nbtries )
393 unsigned int nbok = 0;
394 for (
unsigned int nbp = 0; nbp < nbplanes; ++nbp )
400 if ( ( a != 0 ) || ( b != 0 ) || ( c != 0 ) )
402 ++nb; nbok += checkPlane<Integer, NaivePlaneComputer>( a, b, c, d, diameter, nbtries ) ? 1 : 0;
405 std::cerr <<
"[ERROR] (Simple extension) for plane " << a <<
" * x + "
406 << b <<
" * y + " << c <<
" * z = " << d << std::endl;
409 ++nb; nbok += checkPlaneGroupExtension<Integer, NaivePlaneComputer>( a, b, c, d, diameter, nbtries ) ? 1 : 0;
412 std::cerr <<
"[ERROR] (Group extension) for plane " << a <<
" * x + "
413 << b <<
" * y + " << c <<
" * z = " << d << std::endl;
424 template <
typename Integer,
typename NaivePlaneComputer>
427 int diameter,
unsigned int nbtries )
430 typedef typename NaivePlaneComputer::InternalScalar InternalScalar;
431 typedef typename Point::Component PointInteger;
438 if ( ( absA >= absB ) && ( absA >= absC ) )
440 else if ( ( absB >= absA ) && ( absB >= absC ) )
446 unsigned int nbok = 0;
447 std::vector<Point> points( nbtries );
448 for (
unsigned int i = 0; i != nbtries; ++i )
450 Point & p = points[ i ];
451 p[ 0 ] = getRandomInteger<Integer>( -diameter+1, diameter );
452 p[ 1 ] = getRandomInteger<Integer>( -diameter+1, diameter );
453 p[ 2 ] = getRandomInteger<Integer>( -diameter+1, diameter );
465 << d <<
" <= " << a <<
"*x"
468 <<
" <= d + max(|a|,|b|,|c|)"
470 trace.
info() <<
"- " << points.size() <<
" points tested in diameter " << diameter
473 for (
unsigned int i = 0; i < 3; ++i )
475 std::pair<InternalScalar, InternalScalar> width
476 = NaivePlaneComputer::computeAxisWidth( i, points.begin(), points.end() );
479 trace.
info() <<
" (" << i <<
") width=" << (wn/wd) << std::endl;
480 if ( min < 0.0 ) min = wn/wd;
481 else if ( wn/wd < min ) min = wn/wd;
483 ++nb; nbok += (min < 1.0 ) ? 1 : 0;
484 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") min width = " << min
485 <<
" < 1.0" << std::endl;
486 ++nb; nbok += (0.9 < min ) ? 1 : 0;
487 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") min width = " << min
488 <<
" > 0.9" << std::endl;
493 template <
typename Integer,
typename NaivePlaneComputer>
495 checkWidths(
unsigned int nbplanes,
int diameter,
unsigned int nbtries )
500 unsigned int nbok = 0;
501 for (
unsigned int nbp = 0; nbp < nbplanes; ++nbp )
507 if ( ( a != 0 ) || ( b != 0 ) || ( c != 0 ) )
509 ++nb; nbok += checkWidth<Integer, NaivePlaneComputer>( a, b, c, d, diameter, nbtries ) ? 1 : 0;
512 std::cerr <<
"[ERROR] (checkWidth) for plane " << a <<
" * x + "
513 << b <<
" * y + " << c <<
" * z = " << d << std::endl;
528 unsigned int nbok = 0;
543 trace.
beginBlock (
"Testing block: ChordNaivePlaneComputer instantiation." );
545 Point pt0( 0, 0, 0 );
546 plane.
init( 2, 1, 1 );
547 bool pt0_inside = plane.
extend( pt0 );
548 ++nb; nbok += pt0_inside ==
true ? 1 : 0;
549 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << plane
552 bool pt1_inside = plane.
extend( pt1 );
553 ++nb; nbok += pt1_inside ==
true ? 1 : 0;
554 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") add " << pt1
555 <<
" Plane=" << plane << std::endl;
557 bool pt2_inside = plane.
extend( pt2 );
558 ++nb; nbok += pt2_inside ==
true ? 1 : 0;
559 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") add " << pt2
560 <<
" Plane=" << plane << std::endl;
563 bool pt3_inside = plane.
extend( pt3 );
564 ++nb; nbok += pt3_inside ==
true ? 1 : 0;
565 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") add " << pt3
566 <<
" Plane=" << plane << std::endl;
569 bool pt4_inside = plane.
extend( pt4 );
570 ++nb; nbok += pt4_inside ==
false ? 1 : 0;
571 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") impossible add " << pt4
572 <<
" Plane=" << plane << std::endl;
575 bool pt5_inside = plane.
extend( pt5 );
576 ++nb; nbok += pt5_inside ==
true ? 1 : 0;
577 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") add " << pt5
578 <<
" Plane=" << plane << std::endl;
581 bool pt6_inside = plane.
extend( pt6 );
582 ++nb; nbok += pt6_inside ==
true ? 1 : 0;
583 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") add " << pt6
584 <<
" Plane=" << plane << std::endl;
587 plane2.
init( 2, 1, 1 );
591 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
592 <<
" Plane2=" << plane2 << std::endl;
594 ++nb; nbok += checkPlane<Integer,NaivePlaneComputer>( 11, 5, 19, 20, 100, 100 ) ? 1 : 0;
596 <<
") checkPlane<Integer,NaivePlaneComputer>( 11, 5, 19, 20, 100, 100 )"
599 ++nb; nbok += checkGenericPlane<Integer,GenericNaivePlaneComputer>( 11, 5, 19, 20, 100, 100 ) ? 1 : 0;
601 <<
") checkGenericPlane<Integer,GenericNaivePlaneComputer>( 11, 5, 19, 20, 100, 100 )"
603 ++nb; nbok += checkGenericPlane<Integer,GenericNaivePlaneComputer>( 17, 33, 7, 10, 100, 100 ) ? 1 : 0;
605 <<
") checkGenericPlane<Integer,GenericNaivePlaneComputer>( 17, 33, 7, 10, 100, 100 )"
607 ++nb; nbok += checkPlane<Integer,NaivePlaneComputer>( 15, 8, 13, 15, 100, 100 ) ? 1 : 0;
609 <<
") checkPlane<Integer,NaivePlaneComputer>( 15, 8, 13, 15, 100, 100 )"
611 ++nb; nbok += checkGenericPlane<Integer,GenericNaivePlaneComputer>( 15, 8, 13, 15, 100, 100 ) ? 1 : 0;
613 <<
") checkGenericPlane<Integer,GenericNaivePlaneComputer>( 15, 8, 13, 15, 100, 100 )"
618 trace.
beginBlock (
"Testing block: ChordNaivePlaneComputer vertical instantiation." );
620 Point pppt0( 0, 0, 0 );
621 ppplane.
init( 2, 5, 2 );
622 bool pppt0_inside = ppplane.
extend( pppt0 );
623 ++nb; nbok += pppt0_inside ==
true ? 1 : 0;
624 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << ppplane
626 Point pppt1( 3, 2, 2 );
627 bool pppt1_inside = ppplane.
extend( pppt1 );
628 ++nb; nbok += pppt1_inside ==
true ? 1 : 0;
629 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << ppplane
631 Point pppt2( 0, 0, 1 );
632 bool pppt2_inside = ppplane.
extend( pppt2 );
633 ++nb; nbok += pppt2_inside ==
true ? 1 : 0;
634 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << ppplane
637 bool pppt3_inside = ppplane.
extend( pppt3 );
638 ++nb; nbok += pppt3_inside ==
true ? 1 : 0;
639 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << ppplane
642 bool pppt4_inside = ppplane.
extend( pt4 );
643 ++nb; nbok += pppt4_inside ==
true ? 1 : 0;
644 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << ppplane
650 trace.
beginBlock (
"Testing block: ChordNaivePlaneComputer vertical instantiation 2." );
652 pplane.
init( 1, 1, 1 );
653 Point ppt0( -6, -3, 5 );
654 bool ppt0_inside = pplane.
extend( ppt0 );
655 ++nb; nbok += ppt0_inside ==
true ? 1 : 0;
656 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << pplane
658 Point ppt1( 4, 4, -5 );
659 bool ppt1_inside = pplane.
extend( ppt1 );
660 ++nb; nbok += ppt1_inside ==
true ? 1 : 0;
661 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << pplane
663 Point ppt2( -5, -2, 4 );
664 bool ppt2_inside = pplane.
extend( ppt2 );
665 ++nb; nbok += ppt2_inside ==
true ? 1 : 0;
666 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") Plane=" << pplane
674 template <
typename NaivePlaneComputer>
677 unsigned int nbplanes,
678 unsigned int nbpoints )
680 unsigned int nbok = 0;
682 typedef typename NaivePlaneComputer::InternalScalar Scalar;
683 stringstream ss (stringstream::out);
684 ss <<
"Testing block: Diameter is " << diameter <<
". Check " << nbplanes <<
" planes with " << nbpoints <<
" points each.";
686 ++nb; nbok += checkPlanes<Scalar,NaivePlaneComputer>( nbplanes, diameter, nbpoints ) ? 1 : 0;
688 <<
") checkPlanes<Scalar,NaivePlaneComputer>()"
694 template <
typename GenericNaivePlaneComputer>
697 unsigned int nbplanes,
698 unsigned int nbpoints )
700 unsigned int nbok = 0;
702 typedef typename GenericNaivePlaneComputer::InternalScalar
Integer;
704 typedef typename Point::Coordinate PointInteger;
708 for (
unsigned int j = 0; j < nbplanes; ++j )
714 GenericNaivePlaneComputer plane;
716 if ( ( a >= b ) && ( a >= c ) ) axis = 0;
717 else if ( ( b >= a ) && ( b >= c ) ) axis = 1;
721 std::vector<Point> pts;
722 for (
unsigned int i = 0; i < nbpoints; ++i )
725 p[ 0 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
726 p[ 1 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
727 p[ 2 ] = getRandomInteger<PointInteger>( -diameter+1, diameter );
738 ++nb; nbok += plane.isExtendable( pts.begin(), pts.end() );
740 <<
") plane.isExtendable( pts.begin(), pts.end() )"
742 Point & any0 = pts[ getRandomInteger<int>( 0, pts.size() ) ];
743 pts.push_back( any0 +
Point(1,0,0) );
744 Point & any1 = pts[ getRandomInteger<int>( 0, pts.size() ) ];
745 pts.push_back( any1 +
Point(0,1,0) );
746 Point & any2 = pts[ getRandomInteger<int>( 0, pts.size() ) ];
747 pts.push_back( any2 +
Point(0,0,1) );
748 bool check = ! plane.isExtendable( pts.begin(), pts.end() );
749 ++nb; nbok += check ? 1 : 0;
751 <<
") ! plane.isExtendable( pts.begin(), pts.end() )"
754 trace.
warning() << plane <<
" last=" << pts.back() << std::endl
755 <<
"a=" << a <<
" b=" << b <<
" c=" << c <<
" d=" << d << std::endl;
756 ++nb; nbok += plane.extend( pts.begin(), pts.end() - 3 );
758 <<
") plane.extend( pts.begin(), pts.end() - 3)"
760 ++nb; nbok += ! plane.extend( pts.end() - 3, pts.end() );
762 <<
") ! plane.extend( pts.end() - 3, pts.end() )"
781 && checkManyPlanes<ChordNaivePlaneComputer<Z3i::Space, Z3i::Point, DGtal::int32_t> >( 4, 100, 200 )
783 && checkManyPlanes<ChordNaivePlaneComputer<Z3i::Space, Z3i::Point, DGtal::int32_t> >( 20, 100, 200 )
785 && checkManyPlanes<ChordNaivePlaneComputer<Z3i::Space, Z3i::Point, DGtal::int64_t> >( 2000, 100, 200 )
787 && checkExtendWithManyPoints<ChordGenericNaivePlaneComputer<Z3i::Space, Z3i::Point, DGtal::int64_t> >( 100, 100, 200 );
789 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;
void init(Dimension axis, InternalInteger diameter, InternalInteger widthNumerator=NumberTraits< InternalInteger >::ONE, InternalInteger widthDenominator=NumberTraits< InternalInteger >::ONE)
PointSet::const_iterator ConstIterator
ConstIterator end() const
ConstIterator begin() const
bool isExtendable(const Point &p) const
bool extend(const Point &p)
Aim: A class that recognizes pieces of digital planes of given axis width. When the width is 1,...
Aim: A class that contains the chord-based algorithm for recognizing pieces of digital planes of give...
static Integer abs(IntegerParamType a)
Integer ceilDiv(IntegerParamType na, IntegerParamType nb) const
void beginBlock(const std::string &keyword="")
Point::Coordinate Integer
COBANaivePlaneComputer< Z3, InternalInteger > NaivePlaneComputer
MyDigitalSurface::ConstIterator ConstIterator
Aim: Gathers several functions useful for concept checks.
DGtal is the top-level namespace which contains all DGtal functions and types.
boost::int64_t int64_t
signed 94-bit integer.
DGtal::uint32_t Dimension
Aim: The traits class for all models of Cinteger.
Aim: Defines the concept describing an object that computes some primitive from input points given gr...
Aim: Defines a predicate on a point.
Go to http://www.sgi.com/tech/stl/ForwardContainer.html.
bool checkWidth(Integer a, Integer b, Integer c, Integer d, int diameter, unsigned int nbtries)
bool testChordNaivePlaneComputer()
bool checkPlane(Integer a, Integer b, Integer c, Integer d, int diameter, unsigned int nbtries)
bool checkPlanes(unsigned int nbplanes, int diameter, unsigned int nbtries)
bool checkGenericPlane(Integer a, Integer b, Integer c, Integer d, int diameter, unsigned int nbtries)
bool checkExtendWithManyPoints(unsigned int diameter, unsigned int nbplanes, unsigned int nbpoints)
Integer getRandomInteger(Integer first, Integer after_last)
bool checkWidths(unsigned int nbplanes, int diameter, unsigned int nbtries)
bool checkPlaneGroupExtension(Integer a, Integer b, Integer c, Integer d, int diameter, unsigned int nbtries)
bool checkManyPlanes(unsigned int diameter, unsigned int nbplanes, unsigned int nbpoints)