DGtal  0.9.2
exampleAlphaShape.cpp
1
30 #include <iostream>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/base/IteratorCirculatorTraits.h"
34 #include "DGtal/helpers/StdDefs.h"
35
37 #include "DGtal/geometry/tools/Hull2DHelpers.h"
39 #include "DGtal/geometry/tools/PolarPointComparatorBy2x2DetComputer.h"
40 #include "DGtal/geometry/tools/determinant/AvnaimEtAl2x2DetSignComputer.h"
41 #include "DGtal/geometry/tools/determinant/InHalfPlaneBySimple3x3Matrix.h"
43
44 #include "DGtal/shapes/ShapeFactory.h"
45 #include "DGtal/shapes/Shapes.h"
46
47 #include "DGtal/topology/DigitalSetBoundary.h"
48 #include "DGtal/topology/DigitalSurface.h"
49 #include "DGtal/graph/DepthFirstVisitor.h"
50
51 #include "DGtal/io/boards/Board2D.h"
53
54 using namespace std;
55 using namespace DGtal;
56
58 /*
59  * @brief Procedure that draws on a board a polygon given by a range of vertices.
60  * @param itb begin iterator
61  * @param ite end iterator
62  * @param aBoard any board
63  * @param isClosed bool equal to 'true' for closed polygon, 'false' otherwise.
64  * @tparam ForwardIterator at least a readable and forward iterator
65  * @tparam Board equivalent to Board2D
66  */
67 template <typename ForwardIterator, typename Board>
68 void drawPolygon(const ForwardIterator& itb, const ForwardIterator& ite,
69  Board& aBoard, bool isClosed = true)
70 {
74
75  ForwardIterator it = itb;
76  if (it != ite)
77  {//for the first point
78  Point p1 = *it;
79  Point p = p1;
80  //display
81  aBoard << SetMode( p.className(), "Grid" )
82  << CustomStyle( p.className()+"/Grid", new CustomPenColor( Color::Red ) )
83  << p
84  << CustomStyle( p.className()+"/Grid", new CustomPenColor( Color::Black ) );
85
86  Point prev = p;
87  for (++it; it != ite; ++it, prev = p)
88  {//for all other points
89  //conversion
90  p = *it;
91  //display
92  aBoard << p;
93  if (prev != p)
94  aBoard.drawArrow(prev[0], prev[1], p[0], p[1]);
95  }
96
97  //display the last edge too
98  if (isClosed)
99  {
100  if (prev != p1)
101  aBoard.drawArrow(prev[0], prev[1], p1[0], p1[1]);
102  }
103  }
104 }
105
106
107
112 void alphaShape()
113 {
114
115  //Digitization of a disk of radius 8
116  Ball2D<Z2i::Space> ball(Z2i::Point(0,0), 8);
117  Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
118  Z2i::DigitalSet digitalSet(domain);
119  Shapes<Z2i::Domain>::euclideanShaper(digitalSet, ball);
120
121  //Contour of the digital set
122  Z2i::KSpace kspace;
123  kspace.init(domain.lowerBound()-Z2i::Point(1,1), domain.upperBound()+Z2i::Point(1,1), true);
124  typedef DigitalSetBoundary<Z2i::KSpace, Z2i::DigitalSet> DigitalSurfaceContainer;
125  typedef DigitalSurface<DigitalSurfaceContainer> CustomDigitalSurface;
126  DigitalSurfaceContainer digitalSurfaceContainer( kspace, digitalSet );
127  CustomDigitalSurface digitalSurface( digitalSurfaceContainer );
128
129  //Grid curve
130  Z2i::Curve gridCurve;
132  CustomVisitor visitor( digitalSurface, *digitalSurface.begin() );
133  while ( ! visitor.finished() )
134  {
135  gridCurve.pushBack( visitor.current().first );
136  visitor.expand();
137  }
138
139  //Point set defined as the set of (not duplicated) inner points
140  typedef Z2i::Curve::InnerPointsRange PointRange;
141  PointRange pointsRange = gridCurve.getInnerPointsRange();
142  vector<Z2i::Point> border;
143  unique_copy( pointsRange.begin(), pointsRange.end(), back_inserter( border ) );
144
145  //namespace for hull functions
146  using namespace functions::Hull2D;
147
148  { //alpha = 0
149  trace.info() << " alpha == 0 " << endl;
150  vector<Z2i::Point> res;
151
155  Functor functor(true, 1, 0); //alpha = 0; 1/alpha -> +inf
157  Predicate predicate( functor );
159
161  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
163
164  //display
165  Board2D board;
166  drawPolygon( res.begin(), res.end(), board );
167  board.saveSVG( "AlphaShape0.svg" );
168 #ifdef WITH_CAIRO
169  board.saveCairo("AlphaShape0.png", Board2D::CairoPNG);
170 #endif
171
172  }
173
174  { //alpha = 0
175  trace.info() << " alpha == 0 " << endl;
176  vector<Z2i::Point> res;
177
178  //comparator and functor
180  Functor functor;
182  Predicate predicate( functor );
183
184  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
185
186  //display
187  Board2D board;
188  drawPolygon( res.begin(), res.end(), board );
189  board.saveSVG( "AlphaShape0bis.svg" );
190 #ifdef WITH_CAIRO
191  board.saveCairo("AlphaShape0bis.png", Board2D::CairoPNG);
192 #endif
193
194  }
195
196  //negative alpha shape
197  { //alpha = -1
198  trace.info() << " alpha == -1 " << endl;
199  vector<Z2i::Point> res;
200
204  Functor functor(false, 1, 1); //1/alpha = -sqrt(1/1) = -1
207  Predicate predicate( functor );
208
209  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
210
211  //display
212  Board2D board;
213  drawPolygon( res.begin(), res.end(), board );
214  board.saveSVG( "AlphaShapeM1.svg" );
215 #ifdef WITH_CAIRO
216  board.saveCairo("AlphaShapeM1.png", Board2D::CairoPNG);
217 #endif
218
219  }
220
221  { //alpha = -sqrt(5)
222  trace.info() << " alpha == -sqrt(5) " << endl;
223  vector<Z2i::Point> res;
224
228  Functor functor(false, 5, 1); //1/alpha = -sqrt(5)
231  Predicate predicate( functor );
232
233  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
234
235  //display
236  Board2D board;
237  drawPolygon( res.begin(), res.end(), board );
238  board.saveSVG( "AlphaShapeMSqrt5.svg" );
239 #ifdef WITH_CAIRO
240  board.saveCairo("AlphaShapeMSqrt5.png", Board2D::CairoPNG);
241 #endif
242
243  }
244
245  { //alpha = -5
246  trace.info() << " alpha == -5 " << endl;
247  vector<Z2i::Point> res;
248
252  Functor functor(false, 25, 1); //1/alpha = -sqrt(25/1) = -5
255  Predicate predicate( functor );
256
257  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
258
259  //display
260  Board2D board;
261  drawPolygon( res.begin(), res.end(), board );
262  board.saveSVG( "AlphaShapeM5.svg" );
263 #ifdef WITH_CAIRO
264  board.saveCairo("AlphaShapeM5.png", Board2D::CairoPNG);
265 #endif
266
267  }
268
269  //positive alpha shape
270  {
271  trace.info() << " alpha == 8 " << endl;
272  vector<Z2i::Point> res;
273
277  Functor functor(true, 64, 1); //1/alpha = sqrt(64/1) = 8
279  Predicate predicate( functor );
281
282  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
283
284  //display
285  Board2D board;
286  drawPolygon( res.begin(), res.end(), board );
287  board.saveSVG( "AlphaShapeP8.svg" );
288 #ifdef WITH_CAIRO
289  board.saveCairo("AlphaShapeP8.png", Board2D::CairoPNG);
290 #endif
291
292  }
293
294  //positive alpha shape
295  {
296  trace.info() << " alpha == 9 " << endl;
297  vector<Z2i::Point> res;
298
302  Functor functor(true, 81, 1); //1/alpha = sqrt(81/1) = 9
305  Predicate predicate( functor );
306
307  closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate );
308
309  //display
310  Board2D board;
311  drawPolygon( res.begin(), res.end(), board );
312  board.saveSVG( "AlphaShapeP9.svg" );
313 #ifdef WITH_CAIRO
314  board.saveCairo("AlphaShapeP9.png", Board2D::CairoPNG);
315 #endif
316
317  }
318
319 }
320
328 int main( int argc, char** argv )
329 {
330  trace.beginBlock ( "Example exampleAlphaShape" );
331  trace.info() << "Args:";
332  for ( int i = 0; i < argc; ++i )
333  trace.info() << " " << argv[ i ];
334  trace.info() << endl;
335
336  alphaShape();
337
338  trace.endBlock();
339
340  return 0;
341 }
342 // //
void beginBlock(const std::string &keyword="")
InnerPointsRange getInnerPointsRange() const
Definition: GridCurve.h:462
Trace trace
Definition: Common.h:130
Aim: This class is useful to perform a depth-first exploration of a graph given a starting point or s...
void closedGrahamScanFromAnyPoint(const ForwardIterator &itb, const ForwardIterator &ite, OutputIterator res, const Predicate &aPredicate)
Procedure that retrieves the vertices of the convex hull of a weakly externally visible polygon (WEVP...
STL namespace.
double endBlock()
Aim: Represents a set of n-1-cells in a nD space, together with adjacency relation between these cell...
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as the boundary of a given...
Aim: Class that provides a way of computing the sign of the determinant of a 2x2 matrix from its four...
Aim: Model of the concept StarShaped represents any circle in the plane.
Definition: Ball2D.h:60
Aim: Small adapter to models of COrientationFunctor2. It is a model of concepts::CPointPredicate. It is also a ternary predicate on points, useful for basic geometric tasks such as convex hull computation.
bool init(const Point &lower, const Point &upper, bool isClosed)
Aim: This class implements an orientation functor that provides a way to determine the position of a ...
void pushBack(const SCell &aSCell)
const Point & upperBound() const
DGtal is the top-level namespace which contains all DGtal functions and types.
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: model of CConstBidirectionalRange that adapts any range of elements bounded by two iterators [it...
Go to http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/ForwardTraversal.html.
std::ostream & info()
Modifier class in a Board2D stream. Useful to choose your own mode for a given class. Realizes the concept CDrawableWithBoard2D.
Definition: Board2D.h:247
const Point & lowerBound() const
Aim: describes, in a cellular space of dimension n, a closed or open sequence of signed d-cells (or d...
Definition: GridCurve.h:172
Aim: A utility class for constructing different shapes (balls, diamonds, and others).
Custom style class redefining the pen color. You may use Board2D::Color::None for transparent color...
Definition: Board2D.h:312
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex...
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)...
Definition: Board2D.h:70