32#include "DGtal/base/Common.h"
33#include "DGtal/base/Circulator.h"
35#include "DGtal/kernel/PointVector.h"
36#include "DGtal/geometry/tools/Hull2DHelpers.h"
37#include "DGtal/geometry/tools/PolarPointComparatorBy2x2DetComputer.h"
38#include "DGtal/geometry/tools/determinant/InHalfPlaneBySimple3x3Matrix.h"
39#include "DGtal/geometry/tools/determinant/PredicateFromOrientationFunctor2.h"
40#include "DGtal/io/boards/Board2D.h"
65template <
typename ForwardIterator>
67 const ForwardIterator& first2,
const ForwardIterator& last2 )
69 ASSERT( first2 != last2 );
72 ForwardIterator start1 = find( first1, last1, *first2 );
91 }
while ( (c1 != cEnd1) && (areEqual) );
104 unsigned int nbok = 0;
111 vector<Point> data, g, res;
113 data.push_back(
Point(2,0) );
114 data.push_back(
Point(4,0) );
115 data.push_back(
Point(0,3) );
116 data.push_back(
Point(0,-4) );
117 data.push_back(
Point(3,4) );
118 data.push_back(
Point(5,0) );
119 data.push_back(
Point(4,3) );
120 data.push_back(
Point(0,5) );
121 data.push_back(
Point(-3,-4) );
122 data.push_back(
Point(-5,0) );
123 data.push_back(
Point(-4,-3) );
124 data.push_back(
Point(0,-5) );
125 data.push_back(
Point(3,-4) );
126 data.push_back(
Point(4,-3) );
127 data.push_back(
Point(-3,4) );
128 data.push_back(
Point(-4,3) );
130 g.push_back(
Point(5,0) );
131 g.push_back(
Point(4,3) );
132 g.push_back(
Point(3,4) );
133 g.push_back(
Point(0,5) );
134 g.push_back(
Point(-3,4) );
135 g.push_back(
Point(-4,3) );
136 g.push_back(
Point(-5,0) );
137 g.push_back(
Point(-4,-3) );
138 g.push_back(
Point(-3,-4) );
139 g.push_back(
Point(0,-5) );
140 g.push_back(
Point(3,-4) );
141 g.push_back(
Point(4,-3) );
147 Predicate predicate( functor );
150 using namespace functions::Hull2D;
153 trace.
info() <<
" andrew algorithm " << std::endl;
154 andrewConvexHullAlgorithm( data.begin(), data.end(), back_inserter( res ), predicate );
156 copy(res.begin(), res.end(), ostream_iterator<Point>( cout,
" " ) );
159 if ( (res.size() == g.size()) &&
163 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
167 trace.
info() <<
" graham algorithm " << std::endl;
169 grahamConvexHullAlgorithm( data.begin(), data.end(), back_inserter( res ), predicate, comparator );
171 copy(res.begin(), res.end(), ostream_iterator<Point>( cout,
" " ) );
174 if ( (res.size() == g.size()) &&
178 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
182 trace.
info() <<
" melkman algorithm " << std::endl;
183 sort( data.begin(), data.end() );
184 melkmanConvexHullAlgorithm( data.begin(), data.end(), back_inserter( res ), functor );
186 copy(res.begin(), res.end(), ostream_iterator<Point>( cout,
" " ) );
189 if ( (res.size() == g.size()) &&
193 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
195 trace.
info() <<
"on line convex hull construction" << std::endl;
197 for(vector<Point>::const_iterator it = data.begin(); it != data.end(); it++)
203 unsigned int cvSize = 0;
210 if(res.size() == cvSize && (cvSize ==
ch.size()))
214 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
216 trace.
info() <<
"test copy and [] operator on convex hull:" << std::endl;
218 unsigned int cvSize2 = 0;
223 if(res.size() == cvSize2 &&
ch[0] == ch2[0])
226 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
231 vector<Point> randomData, res1, res2;
232 const int numberOfPoints = 1000;
233 const int numberOfTries = 50;
235 for (
int i = 0; ( (i < numberOfTries)&&(nbok == nb) ); i++)
241 for (
int j = 0; j < numberOfPoints; j++)
242 randomData.push_back(
Point(rand()%256, rand()%256) );
244 andrewConvexHullAlgorithm( randomData.begin(), randomData.end(), back_inserter( res1 ), predicate );
245 grahamConvexHullAlgorithm( randomData.begin(), randomData.end(), back_inserter( res2 ), predicate, comparator );
247 if ( (res1.size() == res2.size()) &&
248 (
circularlyEqual(res1.begin(), res1.end(), res2.begin(), res2.end())) )
251 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
254 sort( randomData.begin(), randomData.end() );
255 melkmanConvexHullAlgorithm( randomData.begin(), randomData.end(), back_inserter( res2 ), functor );
257 if ( (res1.size() == res2.size()) &&
258 (
circularlyEqual(res1.begin(), res1.end(), res2.begin(), res2.end())) )
261 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") " << endl;
276 unsigned int nbok = 0;
291 Point antipodalP, antipodalQ, antipodalS;
299 antipodalP, antipodalQ, antipodalS);
307 aBoard.
drawLine((*it)[0], (*it)[1], (*(it+1))[0], (*(it+1))[1]);
309 aBoard.
drawLine((*it)[0], (*it)[1], (*(
ch.begin()))[0], (*(
ch.begin()))[1]);
315 aBoard.
drawCircle( antipodalS[0], antipodalS[1], 1.0) ;
317 aBoard.
drawCircle(antipodalP[0], antipodalP[1], 1.0);
318 aBoard.
drawCircle(antipodalQ[0], antipodalQ[1], 1.0);
320 aBoard.
drawLine(antipodalP[0], antipodalP[1], antipodalQ[0], antipodalQ[1]);
324 trace.
info() <<
"Expected Thickness HV = " << awaitedThHV << std::endl;
326 trace.
info() <<
"Expected Euclidean Thickness = " << awaitedThE << std::endl;
327 aBoard.
saveEPS(
"testConvexHull2D_Thickness.eps");
330 std::vector<Z2i::RealPoint> hull {
331 {804.56832227024199, -68.471176393526704},
332 {804.96020257363512, -69.494933490400683},
333 {805.35232247974727, -70.519316530915930},
334 {825.15497274857830, -114.34711249674335},
335 {828.67425867587508, -121.69593677670120},
336 {829.05943325037651, -122.39546351563243},
337 {829.42436256177677, -122.73833140123513},
338 {827.82353937509288, -118.87280445059109},
339 {811.06291230576301, -82.124832029926566},
340 {806.83483124583609, -72.890457996792406},
341 {804.92531970702396, -68.803808853026638},
342 {804.55092650722997, -68.125792709291431},
347 std::rotate(hull.begin(), hull.begin() + 1, hull.end());
350 std::rotate(hull.begin(), hull.begin() + 5, hull.end());
353 trace.
info() <<
"Thickness (before change init point) = " << th << std::endl;
354 trace.
info() <<
"Thickness (after change init point) = " << th2 << std::endl;
355 trace.
info() <<
"Thickness (after change init point) = " << th3 << std::endl;
358 thicknessHVb ==
thicknessHV && abs(th - th2) < 0.000001 &&
359 th - 0.604414 < 0.000001 && abs(th - th3) < 0.000001 ;
370int main(
int argc,
char** argv )
374 for (
int i = 0; i < argc; ++i )
379 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Aim: Provides an adapter for classical iterators that can iterate through the underlying data structu...
Aim: Class that implements an orientation functor, ie. it provides a way to compute the orientation o...
Aim: This class implements the on-line algorithm of Melkman for the computation of the convex hull of...
std::deque< Point >::const_iterator ConstIterator
Aim: Implements basic operations that will be used in Point and Vector classes.
Aim: Small adapter to models of COrientationFunctor2. It is a model of concepts::CPointPredicate....
void beginBlock(const std::string &keyword="")
Aim: Class that implements a binary point predicate, which is able to compare the position of two giv...
Board & setPenColor(const DGtal::Color &color)
void drawLine(double x1, double y1, double x2, double y2, int depthValue=-1)
void drawCircle(double x, double y, double radius, int depthValue=-1)
void saveEPS(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
double getThicknessAntipodalPair(const TInputPoint &p, const TInputPoint &q, const TInputPoint &r, const ThicknessDefinition &def)
double computeHullThickness(const ForwardIterator &itb, const ForwardIterator &ite, const ThicknessDefinition &def)
Procedure to compute the convex hull thickness given from different definitions (Horizontal/vertical ...
@ HorizontalVerticalThickness
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::MelkmanConvexHull< Point, Functor > ch
InHalfPlaneBySimple3x3Matrix< Point, double > Functor
bool circularlyEqual(const ForwardIterator &first1, const ForwardIterator &last1, const ForwardIterator &first2, const ForwardIterator &last2)
bool testConvexHullCompThickness()