Main MRPT website > C++ reference for MRPT 1.9.9
CDynamicGrid.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CDynamicGrid_H
10 #define CDynamicGrid_H
11 
12 #include <mrpt/utils/core_defs.h>
13 #include <mrpt/utils/round.h>
14 #include <mrpt/utils/CStream.h>
15 #include <vector>
16 #include <string>
17 #include <cmath>
18 
19 namespace mrpt
20 {
21 namespace utils
22 {
23 namespace internal
24 {
25 // Aux class.
27 {
28  bool saveToTextFile(const std::string& fileName) const;
29  virtual unsigned int getSizeX() const = 0;
30  virtual unsigned int getSizeY() const = 0;
31  virtual float getCellAsFloat(unsigned int cx, unsigned int cy) const = 0;
32 };
33 } // internal
34 
35 /** A 2D grid of dynamic size which stores any kind of data at each cell.
36  * \tparam T The type of each cell in the 2D grid.
37  * \ingroup mrpt_base_grp
38  */
39 template <class T>
41 {
42  protected:
43  /** The cells */
44  std::vector<T> m_map;
45  /** Used only from logically const method that really need to modify the
46  * object */
47  inline std::vector<T>& m_map_castaway_const() const
48  {
49  return const_cast<std::vector<T>&>(m_map);
50  }
51 
53  size_t m_size_x, m_size_y;
54 
55  public:
56  /** Constructor */
58  double x_min = -10.0, double x_max = 10.0, double y_min = -10.0f,
59  double y_max = 10.0f, double resolution = 0.10f)
60  : m_map(),
61  m_x_min(),
62  m_x_max(),
63  m_y_min(),
64  m_y_max(),
65  m_resolution(),
66  m_size_x(),
67  m_size_y()
68  {
69  setSize(x_min, x_max, y_min, y_max, resolution);
70  }
71 
72  /** Destructor */
73  virtual ~CDynamicGrid() {}
74  /** Changes the size of the grid, ERASING all previous contents.
75  * If \a fill_value is left as nullptr, the contents of cells may be
76  * undefined (some will remain with
77  * their old values, the new ones will have the default cell value, but
78  * the location of old values
79  * may change wrt their old places).
80  * If \a fill_value is not nullptr, it is assured that all cells will have
81  * a copy of that value after resizing.
82  * \sa resize, fill
83  */
84  void setSize(
85  const double x_min, const double x_max, const double y_min,
86  const double y_max, const double resolution,
87  const T* fill_value = nullptr)
88  {
89  // Adjust sizes to adapt them to full sized cells acording to the
90  // resolution:
91  m_x_min = resolution * round(x_min / resolution);
92  m_y_min = resolution * round(y_min / resolution);
93  m_x_max = resolution * round(x_max / resolution);
94  m_y_max = resolution * round(y_max / resolution);
95 
96  // Res:
97  m_resolution = resolution;
98 
99  // Now the number of cells should be integers:
102 
103  // Cells memory:
104  if (fill_value)
105  m_map.assign(m_size_x * m_size_y, *fill_value);
106  else
107  m_map.resize(m_size_x * m_size_y);
108  }
109 
110  /** Erase the contents of all the cells. */
111  void clear()
112  {
113  m_map.clear();
114  m_map.resize(m_size_x * m_size_y);
115  }
116 
117  /** Fills all the cells with the same value
118  */
119  inline void fill(const T& value)
120  {
121  for (typename std::vector<T>::iterator it = m_map.begin();
122  it != m_map.end(); ++it)
123  *it = value;
124  }
125 
126  /** Changes the size of the grid, maintaining previous contents.
127  * \sa setSize
128  */
129  virtual void resize(
130  double new_x_min, double new_x_max, double new_y_min, double new_y_max,
131  const T& defaultValueNewCells, double additionalMarginMeters = 2.0)
132  {
133  // Is resize really necesary?
134  if (new_x_min >= m_x_min && new_y_min >= m_y_min &&
135  new_x_max <= m_x_max && new_y_max <= m_y_max)
136  return;
137 
138  if (new_x_min > m_x_min) new_x_min = m_x_min;
139  if (new_x_max < m_x_max) new_x_max = m_x_max;
140  if (new_y_min > m_y_min) new_y_min = m_y_min;
141  if (new_y_max < m_y_max) new_y_max = m_y_max;
142 
143  // Additional margin:
144  if (additionalMarginMeters > 0)
145  {
146  if (new_x_min < m_x_min)
147  new_x_min = floor(new_x_min - additionalMarginMeters);
148  if (new_x_max > m_x_max)
149  new_x_max = ceil(new_x_max + additionalMarginMeters);
150  if (new_y_min < m_y_min)
151  new_y_min = floor(new_y_min - additionalMarginMeters);
152  if (new_y_max > m_y_max)
153  new_y_max = ceil(new_y_max + additionalMarginMeters);
154  }
155 
156  // Adjust sizes to adapt them to full sized cells acording to the
157  // resolution:
158  if (fabs(new_x_min / m_resolution - round(new_x_min / m_resolution)) >
159  0.05f)
160  new_x_min = m_resolution * round(new_x_min / m_resolution);
161  if (fabs(new_y_min / m_resolution - round(new_y_min / m_resolution)) >
162  0.05f)
163  new_y_min = m_resolution * round(new_y_min / m_resolution);
164  if (fabs(new_x_max / m_resolution - round(new_x_max / m_resolution)) >
165  0.05f)
166  new_x_max = m_resolution * round(new_x_max / m_resolution);
167  if (fabs(new_y_max / m_resolution - round(new_y_max / m_resolution)) >
168  0.05f)
169  new_y_max = m_resolution * round(new_y_max / m_resolution);
170 
171  // Change the map size: Extensions at each side:
172  unsigned int extra_x_izq = round((m_x_min - new_x_min) / m_resolution);
173  unsigned int extra_y_arr = round((m_y_min - new_y_min) / m_resolution);
174 
175  unsigned int new_size_x = round((new_x_max - new_x_min) / m_resolution);
176  unsigned int new_size_y = round((new_y_max - new_y_min) / m_resolution);
177 
178  // Reserve new memory:
179  typename std::vector<T> new_map;
180  new_map.resize(new_size_x * new_size_y, defaultValueNewCells);
181 
182  // Copy previous rows:
183  unsigned int x, y;
184  typename std::vector<T>::iterator itSrc, itDst;
185  for (y = 0; y < m_size_y; y++)
186  {
187  for (x = 0, itSrc = (m_map.begin() + y * m_size_x),
188  itDst =
189  (new_map.begin() + extra_x_izq +
190  (y + extra_y_arr) * new_size_x);
191  x < m_size_x; ++x, ++itSrc, ++itDst)
192  {
193  *itDst = *itSrc;
194  }
195  }
196 
197  // Update the new map limits:
198  m_x_min = new_x_min;
199  m_x_max = new_x_max;
200  m_y_min = new_y_min;
201  m_y_max = new_y_max;
202 
203  m_size_x = new_size_x;
204  m_size_y = new_size_y;
205 
206  // Keep the new map only:
207  m_map.swap(new_map);
208  }
209 
210  /** Returns a pointer to the contents of a cell given by its coordinates, or
211  * nullptr if it is out of the map extensions.
212  */
213  inline T* cellByPos(double x, double y)
214  {
215  const int cx = x2idx(x);
216  const int cy = y2idx(y);
217  if (cx < 0 || cx >= static_cast<int>(m_size_x)) return nullptr;
218  if (cy < 0 || cy >= static_cast<int>(m_size_y)) return nullptr;
219  return &m_map[cx + cy * m_size_x];
220  }
221  /** \overload */
222  inline const T* cellByPos(double x, double y) const
223  {
224  const int cx = x2idx(x);
225  const int cy = y2idx(y);
226  if (cx < 0 || cx >= static_cast<int>(m_size_x)) return nullptr;
227  if (cy < 0 || cy >= static_cast<int>(m_size_y)) return nullptr;
228  return &m_map[cx + cy * m_size_x];
229  }
230 
231  /** Returns a pointer to the contents of a cell given by its cell indexes,
232  * or nullptr if it is out of the map extensions.
233  */
234  inline T* cellByIndex(unsigned int cx, unsigned int cy)
235  {
236  if (cx >= m_size_x || cy >= m_size_y)
237  return nullptr;
238  else
239  return &m_map[cx + cy * m_size_x];
240  }
241 
242  /** Returns a pointer to the contents of a cell given by its cell indexes,
243  * or nullptr if it is out of the map extensions.
244  */
245  inline const T* cellByIndex(unsigned int cx, unsigned int cy) const
246  {
247  if (cx >= m_size_x || cy >= m_size_y)
248  return nullptr;
249  else
250  return &m_map[cx + cy * m_size_x];
251  }
252 
253  /** Returns the horizontal size of grid map in cells count */
254  inline size_t getSizeX() const { return m_size_x; }
255  /** Returns the vertical size of grid map in cells count */
256  inline size_t getSizeY() const { return m_size_y; }
257  /** Returns the "x" coordinate of left side of grid map */
258  inline double getXMin() const { return m_x_min; }
259  /** Returns the "x" coordinate of right side of grid map */
260  inline double getXMax() const { return m_x_max; }
261  /** Returns the "y" coordinate of top side of grid map */
262  inline double getYMin() const { return m_y_min; }
263  /** Returns the "y" coordinate of bottom side of grid map */
264  inline double getYMax() const { return m_y_max; }
265  /** Returns the resolution of the grid map */
266  inline double getResolution() const { return m_resolution; }
267  /** Transform a coordinate values into cell indexes */
268  inline int x2idx(double x) const
269  {
270  return static_cast<int>((x - m_x_min) / m_resolution);
271  }
272  inline int y2idx(double y) const
273  {
274  return static_cast<int>((y - m_y_min) / m_resolution);
275  }
276  inline int xy2idx(double x, double y) const
277  {
278  return x2idx(x) + y2idx(y) * m_size_x;
279  }
280 
281  /** Transform a global (linear) cell index value into its corresponding
282  * (x,y) cell indexes. */
283  inline void idx2cxcy(const int& idx, int& cx, int& cy) const
284  {
285  cx = idx % m_size_x;
286  cy = idx / m_size_x;
287  }
288 
289  /** Transform a cell index into a coordinate value of the cell central point
290  */
291  inline double idx2x(int cx) const
292  {
293  return m_x_min + (cx + 0.5) * m_resolution;
294  }
295  inline double idx2y(int cy) const
296  {
297  return m_y_min + (cy + 0.5) * m_resolution;
298  }
299 
300  /** Get the entire grid as a matrix.
301  * \tparam MAT The type of the matrix, typically a
302  * mrpt::math::CMatrixDouble.
303  * \param[out] m The output matrix; will be set automatically to the
304  * correct size.
305  * Entry (cy,cx) in the matrix contains the grid cell with indices
306  * (cx,cy).
307  * \note This method will compile only for cell types that can be
308  * converted to the type of the matrix elements (e.g. double).
309  */
310  template <class MAT>
311  void getAsMatrix(MAT& m) const
312  {
313  m.setSize(m_size_y, m_size_x);
314  if (m_map.empty()) return;
315  const T* c = &m_map[0];
316  for (size_t cy = 0; cy < m_size_y; cy++)
317  for (size_t cx = 0; cx < m_size_x; cx++) m.set_unsafe(cy, cx, *c++);
318  }
319 
320  /** The user must implement this in order to provide "saveToTextFile" a way
321  * to convert each cell into a numeric value */
322  virtual float cell2float(const T& c) const
323  {
325  return 0;
326  }
327  /** Saves a float representation of the grid (via "cell2float()") to a text
328  * file. \return false on error */
329  bool saveToTextFile(const std::string& fileName) const
330  {
331  struct aux_saver : public internal::dynamic_grid_txt_saver
332  {
333  aux_saver(const CDynamicGrid<T>& obj) : m_obj(obj) {}
334  virtual unsigned int getSizeX() const { return m_obj.getSizeX(); }
335  virtual unsigned int getSizeY() const { return m_obj.getSizeY(); }
336  virtual float getCellAsFloat(unsigned int cx, unsigned int cy) const
337  {
338  return m_obj.cell2float(
339  m_obj.m_map[cx + cy * m_obj.getSizeX()]);
340  }
341  const CDynamicGrid<T>& m_obj;
342  };
343  aux_saver aux(*this);
344  return aux.saveToTextFile(fileName);
345  }
346 
347  protected:
349  {
350  out << m_x_min << m_x_max << m_y_min << m_y_max;
351  out << m_resolution;
352  out << static_cast<uint32_t>(m_size_x)
353  << static_cast<uint32_t>(m_size_y);
354  }
356  mrpt::utils::CStream& in, bool cast_from_float = false)
357  {
358  if (!cast_from_float)
359  {
360  in >> m_x_min >> m_x_max >> m_y_min >> m_y_max;
361  in >> m_resolution;
362  }
363  else
364  {
365  float xmin, xmax, ymin, ymax, res;
366  in >> xmin >> xmax >> ymin >> ymax >> res;
367  m_x_min = xmin;
368  m_x_max = xmax;
369  m_y_min = ymin;
370  m_y_max = ymax;
371  m_resolution = res;
372  }
373  uint32_t nX, nY;
374  in >> nX >> nY;
375  m_size_x = nX;
376  m_size_y = nY;
377  m_map.resize(nX * nY);
378  }
379 
380 }; // end of CDynamicGrid<>
381 
382 } // End of namespace
383 } // end of namespace
384 #endif
std::vector< T > & m_map_castaway_const() const
Used only from logically const method that really need to modify the object.
Definition: CDynamicGrid.h:47
double getXMax() const
Returns the "x" coordinate of right side of grid map.
Definition: CDynamicGrid.h:260
void clear()
Erase the contents of all the cells.
Definition: CDynamicGrid.h:111
int xy2idx(double x, double y) const
Definition: CDynamicGrid.h:276
virtual float cell2float(const T &c) const
The user must implement this in order to provide "saveToTextFile" a way to convert each cell into a n...
Definition: CDynamicGrid.h:322
virtual unsigned int getSizeY() const =0
int x2idx(double x) const
Transform a coordinate values into cell indexes.
Definition: CDynamicGrid.h:268
Scalar * iterator
Definition: eigen_plugins.h:26
double getYMin() const
Returns the "y" coordinate of top side of grid map.
Definition: CDynamicGrid.h:262
double getXMin() const
Returns the "x" coordinate of left side of grid map.
Definition: CDynamicGrid.h:258
size_t getSizeY() const
Returns the vertical size of grid map in cells count.
Definition: CDynamicGrid.h:256
virtual void resize(double new_x_min, double new_x_max, double new_y_min, double new_y_max, const T &defaultValueNewCells, double additionalMarginMeters=2.0)
Changes the size of the grid, maintaining previous contents.
Definition: CDynamicGrid.h:129
void fill(const T &value)
Fills all the cells with the same value.
Definition: CDynamicGrid.h:119
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
void idx2cxcy(const int &idx, int &cx, int &cy) const
Transform a global (linear) cell index value into its corresponding (x,y) cell indexes.
Definition: CDynamicGrid.h:283
int y2idx(double y) const
Definition: CDynamicGrid.h:272
bool saveToTextFile(const std::string &fileName) const
T * cellByPos(double x, double y)
Returns a pointer to the contents of a cell given by its coordinates, or nullptr if it is out of the ...
Definition: CDynamicGrid.h:213
double idx2y(int cy) const
Definition: CDynamicGrid.h:295
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
A 2D grid of dynamic size which stores any kind of data at each cell.
Definition: CDynamicGrid.h:40
double getYMax() const
Returns the "y" coordinate of bottom side of grid map.
Definition: CDynamicGrid.h:264
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
const GLubyte * c
Definition: glext.h:6313
std::vector< T > m_map
The cells.
Definition: CDynamicGrid.h:44
size_t getSizeX() const
Returns the horizontal size of grid map in cells count.
Definition: CDynamicGrid.h:254
CDynamicGrid(double x_min=-10.0, double x_max=10.0, double y_min=-10.0f, double y_max=10.0f, double resolution=0.10f)
Constructor.
Definition: CDynamicGrid.h:57
virtual unsigned int getSizeX() const =0
GLsizei const GLchar ** string
Definition: glext.h:4101
T * cellByIndex(unsigned int cx, unsigned int cy)
Returns a pointer to the contents of a cell given by its cell indexes, or nullptr if it is out of the...
Definition: CDynamicGrid.h:234
double idx2x(int cx) const
Transform a cell index into a coordinate value of the cell central point.
Definition: CDynamicGrid.h:291
virtual float getCellAsFloat(unsigned int cx, unsigned int cy) const =0
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double getResolution() const
Returns the resolution of the grid map.
Definition: CDynamicGrid.h:266
const T * cellByPos(double x, double y) const
Definition: CDynamicGrid.h:222
virtual ~CDynamicGrid()
Destructor.
Definition: CDynamicGrid.h:73
const T * cellByIndex(unsigned int cx, unsigned int cy) const
Returns a pointer to the contents of a cell given by its cell indexes, or nullptr if it is out of the...
Definition: CDynamicGrid.h:245
void setSize(const double x_min, const double x_max, const double y_min, const double y_max, const double resolution, const T *fill_value=nullptr)
Changes the size of the grid, ERASING all previous contents.
Definition: CDynamicGrid.h:84
bool saveToTextFile(const std::string &fileName) const
Saves a float representation of the grid (via "cell2float()") to a text file.
Definition: CDynamicGrid.h:329
GLuint in
Definition: glext.h:7274
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:25
void dyngridcommon_writeToStream(mrpt::utils::CStream &out) const
Definition: CDynamicGrid.h:348
GLenum GLint GLint y
Definition: glext.h:3538
GLsizei const GLfloat * value
Definition: glext.h:4117
GLuint res
Definition: glext.h:7268
GLenum GLint x
Definition: glext.h:3538
unsigned __int32 uint32_t
Definition: rptypes.h:47
void dyngridcommon_readFromStream(mrpt::utils::CStream &in, bool cast_from_float=false)
Definition: CDynamicGrid.h:355
void getAsMatrix(MAT &m) const
Get the entire grid as a matrix.
Definition: CDynamicGrid.h:311



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019