46 #include "DGtal/base/Common.h"
47 #include "DGtal/helpers/StdDefs.h"
49 #include "DGtal/arithmetic/LighterSternBrocot.h"
50 #include "DGtal/arithmetic/Pattern.h"
52 #include "DGtal/io/boards/Board2D.h"
53 #include "DGtal/io/Color.h"
58 using namespace DGtal;
110 template <
typename Po
int>
111 struct OddConvexHullMap {
123 OddConvexHullMap(
const Vector& aShift =
Vector(1,-1))
149 template <
typename Po
int>
150 struct EvenConvexHullMap {
163 EvenConvexHullMap(
const Point& aPoint,
const Vector& aShift =
Vector(1,-1))
164 : myZn(aPoint), myS(aShift) {}
174 return myZn - aP + myS;
195 template <
typename Board,
typename Po
int>
196 void drawSegment(Board& aBoard,
const Point& aP,
const Point& aQ)
198 aBoard.drawLine(aP[0], aP[1], aQ[0], aQ[1]);
216 template <
typename Board,
typename Iterator,
typename Functor>
217 void drawSegments(Board& aBoard,
218 const Iterator& itb,
const Iterator& ite,
224 Iterator prevIt = it;
226 for ( ; it != ite; ++prevIt, ++it)
228 drawSegment( aBoard, aF(*prevIt), aF(*it) );
250 template<
typename Fraction,
typename Container>
251 void fillConvergents(
const Fraction& aZn,
252 Container& odd, Container& even)
254 typedef typename Container::value_type
Vector;
256 for (
typename Fraction::Quotient i = 1; i <= aZn.k(); ++i)
258 Fraction zk = aZn.reduced(i);
259 if (((aZn.k() - i)%2) == 1 )
261 odd.push_back(
Vector(zk.q(),zk.p()));
265 even.push_back(
Vector(zk.q(),zk.p()));
284 template <
typename Pattern,
typename Integer>
285 void displayConvexHull(
const Pattern& aP,
const Integer& aD,
bool withFDT =
false)
289 typedef std::vector<Vector> Convergents;
295 Convergents oddConvergents, evenConvergents;
298 Fraction zn = aP.
slope();
302 Fraction znm1 = zn.father();
304 oddConvergents.push_back(
Vector(znm1.q(),znm1.p()));
306 evenConvergents.push_back(
Vector(znm1.q(),znm1.p()));
309 fillConvergents( zn, oddConvergents, evenConvergents );
314 aBoard <<
SetMode( Zn.className(),
"Grid" );
319 OddConvexHullMap<Point> oddH;
320 drawSegments( aBoard, oddConvergents.begin(), oddConvergents.end(), oddH );
322 EvenConvexHullMap<Point> evenH(Zn);
323 drawSegments( aBoard, evenConvergents.begin(), evenConvergents.end(), evenH );
326 drawSegment( aBoard,
Point(0,0), Zn );
327 if (evenConvergents.size() != 0)
329 drawSegment( aBoard, evenH(*evenConvergents.rbegin()), Zn );
330 if (oddConvergents.size() != 0)
332 drawSegment( aBoard,
Point(0,0), oddH(*oddConvergents.rbegin()) );
334 oddH(*oddConvergents.begin()),
335 evenH(*evenConvergents.begin()) );
339 drawSegment( aBoard,
Point(0,0), evenH(*evenConvergents.rbegin()) );
347 if (evenConvergents.size() != 0)
350 evenH(*evenConvergents.rbegin()) );
352 typedef typename Convergents::const_reverse_iterator RI;
353 RI oddRit = oddConvergents.rbegin();
354 RI evenRit = evenConvergents.rbegin();
355 bool hasToContinue =
true;
356 while (hasToContinue)
358 if (oddRit != oddConvergents.rend())
365 hasToContinue =
false;
368 if ( (hasToContinue) && (evenRit != evenConvergents.rend()) )
375 hasToContinue =
false;
399 template <
typename Board,
typename Po
int>
400 void drawTriangle(Board& aBoard,
403 aBoard.drawTriangle( aP[0], aP[1], aQ[0], aQ[1], aR[0], aR[1] );
415 struct InDirectBezoutComputer
424 template<
typename Pattern>
426 getPositiveBezout(
const Pattern& aP)
const
438 template<
typename Pattern>
440 getNegativeBezout(
const Pattern& aP)
const
442 return aP.
slope().even()
458 struct DirectBezoutComputer
467 template<
typename Pattern>
469 getPositiveBezout(
const Pattern& aP)
const
471 return aP.
slope().even()
483 template<
typename Pattern>
485 getNegativeBezout(
const Pattern& aP)
const
510 template <
typename Board,
typename Pattern,
typename BezoutComputer>
511 void displayPartialCDT(Board& aBoard,
514 const BezoutComputer& aBC )
520 Fraction f = aP.
slope();
521 if ( (f.p() >= 1)&&(f.q() >= 1) )
523 Point O = aStartingPoint;
524 Point Zn = aStartingPoint + aP.
v();
525 Vector v1 = aBC.getNegativeBezout(aP);
526 Point B = aStartingPoint + v1;
527 drawTriangle(aBoard, O, Zn, B);
529 if ( (f.p() > 1)||(f.q() > 1) )
533 displayPartialCDT(aBoard,
Pattern(Fraction(v1[1],v1[0])), O, aBC);
535 Vector v2 = aBC.getPositiveBezout(aP);
536 displayPartialCDT(aBoard,
Pattern(Fraction(v2[1],v2[0])), B, aBC);
552 template <
typename Pattern,
typename Integer>
553 void displayCDT(
const Pattern& aP,
const Integer& aD)
559 Fraction zn = aP.
slope();
564 aBoard <<
SetMode( Zn.className(),
"Grid" );
569 for (Integer i = 0; i < aD; ++i)
571 displayPartialCDT( aBoard, aP,
Point(i*zn.q(), i*zn.p()), InDirectBezoutComputer() );
577 typedef std::vector<Vector> Convergents;
578 typedef typename std::vector<Vector>::const_reverse_iterator
ReverseIterator;
579 Convergents oddConvergents, evenConvergents;
580 fillConvergents( zn, oddConvergents, evenConvergents );
582 Point rPStartingPoint;
584 OddConvexHullMap<Point> oddH;
588 Point aStartingPoint = oddH( *oddConvergents.rbegin() );
590 Point p = aStartingPoint;
594 for (++it; it != ite; ++it)
596 displayPartialCDT( aBoard,
Pattern( (*it)[1], (*it)[0] ), p, DirectBezoutComputer() );
603 EvenConvexHullMap<Point> evenH(Zn);
607 Point aStartingPoint = evenH( *evenConvergents.rbegin() );
609 Point p = aStartingPoint;
611 for ( ; it != ite; ++it)
614 displayPartialCDT( aBoard,
Pattern( (*it)[1], (*it)[0] ), p, DirectBezoutComputer() );
619 for (Integer i = 0; i < (aD-1); ++i)
621 Point p = rPStartingPoint + i*aP.
v();
622 displayPartialCDT( aBoard, aP, p, DirectBezoutComputer() );
637 void missingParam(std::string param)
639 trace.
error() <<
" Parameter: " << param <<
" is required...";
654 int main(
int argc,
char **argv)
666 app.description(
"Draw the Delaunay triangulation of a pattern using DGtal library. Example: patternTriangulation -a 5 -b 8 ");
667 app.add_option(
"-a,--aparam",a,
"pattern a parameter")
669 app.add_option(
"-b,--bparam",b,
"pattern b parameter")
671 app.add_option(
"-d,--delta",d,
"number of repetitions");
672 app.add_option(
"--triangulation,-t",type,
"output:\n\tClosest-point Delaunay triangulation {CDT}\n\tFarthest-point Delaunay triangulation {FDT}\n\tConvex hull {CH}",
true);
675 app.get_formatter()->column_width(40);
676 CLI11_PARSE(app, argc, argv);
682 if ( (a < 0) || (b <= 0) )
684 trace.
error() <<
" parameters a and b should be strictly positive.";
690 trace.
error() <<
" parameter a should be strictly less than b.";
697 trace.
error() <<
" parameter d should be strictly positive";
701 trace.
info() <<
"a=" << a <<
", b=" << b <<
", d=" << d << std::endl;
705 typedef SB::Fraction Fraction;
712 displayCDT(pattern, d);
714 else if (type ==
"FDT")
716 displayConvexHull(pattern, d,
true);
718 else if (type ==
"CH")
720 displayConvexHull(pattern, d);
724 trace.
error() <<
" unknown output type. Try -h option. ";
int main(int argc, char **argv)
typename Self::Point Point
Pattern previousPattern() const
Point2I U(Quotient k) const
Board & setLineStyle(Shape::LineStyle style)
void saveEPS(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Board & setPenColor(const DGtal::Color &color)
HyperRectDomain< Space > Domain
Trace trace(traceWriterTerm)