DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
exampleFMM2D.cpp
1 
32 
33 #include <iostream>
34 #include <iomanip>
35 #include <functional>
36 
37 #include "DGtal/base/Common.h"
38 
39 //space, domain and image
40 #include "DGtal/kernel/SpaceND.h"
41 #include "DGtal/kernel/domains/HyperRectDomain.h"
42 #include "DGtal/kernel/sets/DigitalSetFromMap.h"
43 #include "DGtal/images/ImageContainerBySTLMap.h"
44 #include "DGtal/topology/SCellsFunctors.h"
45 
46 //tracking
47 #include "DGtal/topology/helpers/Surfaces.h"
48 
49 
50 //FMM
51 #include "DGtal/geometry/volumes/distance/FMM.h"
52 
53 //Display
54 #include "DGtal/io/colormaps/HueShadeColorMap.h"
55 #include "DGtal/io/boards/Board2D.h"
56 
58 
59 using namespace std;
60 using namespace DGtal;
61 
62 
64 // ball
65 template <typename TPoint>
66 class BallPredicate
67 {
68 public:
69  typedef TPoint Point;
70 
71 public:
72 
73  BallPredicate(double aCx, double aCy, double aR ):
74  myCx(aCx), myCy(aCy), myR(aR)
75  { ASSERT(myR > 0); };
76 
77  bool operator()(const TPoint& aPoint) const
78  {
79  double d = std::sqrt( std::pow( (myCx-aPoint[0] ), 2)
80  + std::pow( (myCy-aPoint[1] ), 2) );
81  if (d <= myR) return true;
82  else return false;
83  };
84 private:
85  double myCx, myCy, myR;
86 };
87 
88 template <typename TPoint>
89 class BallFunctor
90 {
91 public:
92  typedef TPoint Point;
93  typedef double Value;
94 public:
95 
96  BallFunctor(double aCx, double aCy, double aR ):
97  myCx(aCx), myCy(aCy), myR(aR)
98  { ASSERT(myR > 0); };
99 
100  Value operator()(const TPoint& aPoint) const
101  {
102  double d = std::sqrt( std::pow( (myCx-aPoint[0] ), 2)
103  + std::pow( (myCy-aPoint[1] ), 2) );
104  return (d - myR);
105  };
106 private:
107  double myCx, myCy, myR;
108 };
109 
110 template< typename TIterator >
111 void draw( const TIterator& itb, const TIterator& ite, const int& size, std::string basename)
112 {
113  typedef typename std::iterator_traits<TIterator>::value_type Pair;
114  typedef typename Pair::first_type Point;
115  typedef typename Pair::second_type Value;
116  HueShadeColorMap<unsigned char, 2> colorMap(0,3*size);
117 
118  Board2D b;
120 
121  for (TIterator it = itb; it != ite; ++it)
122  {
123  Point p = it->first;
124  b << CustomStyle( p.className(), new CustomFillColor( colorMap( it->second) ) );
125  b << p;
126  }
127 
128  std::stringstream s;
129  s << basename << ".eps";
130  b.saveEPS(s.str().c_str());
131 }
132 
133 
135 // main task
136 bool perform()
137 {
138 
139  static const DGtal::Dimension dimension = 2;
140 
141  //Domain
143  typedef Domain::Point Point;
144  int size = 50;
145  Domain d(Point::diagonal(-size), Point::diagonal(size));
146  double h = 1.0/(double)size;
147 
148  //Predicate, which implicitely define the interface
149  int radius = (size/2);
150  typedef BallPredicate<Point> Predicate;
151  Predicate predicate( 0, 0, radius );
152  trace.info() << " # circle of radius 0.5 "
153  << "digitized in a square of size 1 "
154  << "at step h=" << h << endl;
155 
156  //Digital circle generation
158  KSpace K; K.init( Point::diagonal(-size), Point::diagonal(size), true);
160  KSpace::SCell bel = Surfaces<KSpace>::findABel( K, predicate, 10000 );
161  std::vector<KSpace::SCell> vSCells;
162  Surfaces<KSpace>::track2DBoundary( vSCells, K, SAdj, predicate, bel );
163 
164  //Image of distance values and associated set
165  typedef ImageContainerBySTLMap<Domain,double> DistanceImage;
167  DistanceImage dmap( d );
168  Set set(dmap);
169 
170  //initialisation
175 
176  typedef BallFunctor<Point> Functor;
177  Functor functor( 0, 0, radius );
178  FMM::initFromBelsRange( K,
179  vSCells.begin(), vSCells.end(),
180  functor, dmap, set );
181 
182  //Image of speed values
183  typedef ImageContainerBySTLMap<Domain,double> SpeedImage;
184  SpeedImage smap(d, 0.0);
185 
186  SCellToIncidentPoints<KSpace> belToPair( K );
187  for (std::vector<KSpace::SCell>::const_iterator it = vSCells.begin(),
188  itEnd = vSCells.end(); it != itEnd; ++it)
189  {
190  SCellToIncidentPoints<KSpace>::Output pair = belToPair( *it );
191  Point in = pair.first;
192  Point out = pair.second;
193  //speed equal to the x-coordinate
194  smap.setValue( in, in[0] );
195  smap.setValue( out, out[0] );
196  }
197 
198 
199  //Extrapolating speed away from the interface
200  SpeedExtrapolator<DistanceImage, Set, SpeedImage> speedFunctor(dmap, set, smap);
201  const double maxWidth = 10.0;
202  Distance distFunctor(dmap, set);
203  FMM fmm(dmap, set, d.predicate(), d.size(), maxWidth, distFunctor );
204  Point lastPt = Point::diagonal(0); //last point
205  double lastDist = 0.0; //its distance
206  while ( (fmm.computeOneStep( lastPt, lastDist ))
207  && (std::abs( lastDist ) < maxWidth) )
208  {
209  //new speed value
210  smap.setValue( lastPt, speedFunctor( lastPt ) );
211  }
212 
213  trace.info() << fmm << std::endl;
214 
215  //display - you should see constant colors
216  //on rays normal to the interface.
217  std::stringstream s;
218  s << "SpeedExt-" << radius;
219  draw(smap.begin(), smap.end(), size, s.str());
220 
221  return true;
222 
223 }
224 
225 
226 
227 
228 
230 // Standard services - public :
231 
232 int main ( int argc, char** argv )
233 {
234  trace.beginBlock ( "Example 2d FMM" );
235  trace.info() << "Args:";
236  for ( int i = 0; i < argc; ++i )
237  trace.info() << " " << argv[ i ];
238  trace.info() << endl;
239 
240  //computation
241  perform();
242 
243  trace.endBlock();
244  return 1;
245 }
246 // //