Main MRPT website > C++ reference for MRPT 1.9.9
CDynamicGrid3D.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 
10 #pragma once
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 /** A 3D rectangular grid of dynamic size which stores any kind of data at each
24 * voxel.
25 * \tparam T The type of each voxel in the grid.
26 */
27 template <class T>
29 {
30  public:
31  /** Constructor */
33  double x_min = -1.0, double x_max = 1.0, double y_min = -1.0,
34  double y_max = +1.0, double z_min = -1.0, double z_max = 1.0,
35  double resolution_xy = 0.5, double resolution_z = 0.5)
36  : m_map()
37  {
38  setSize(
39  x_min, x_max, y_min, y_max, z_min, z_max, resolution_xy,
40  resolution_z);
41  }
42 
43  /** Changes the size of the grid, maintaining previous contents.
44  * \sa setSize
45  */
46  virtual void resize(
47  double new_x_min, double new_x_max, double new_y_min, double new_y_max,
48  double new_z_min, double new_z_max, const T& defaultValueNewCells,
49  double additionalMarginMeters = 2.0)
50  {
51  // Is resize really necesary?
52  if (new_x_min >= m_x_min && new_y_min >= m_y_min &&
53  new_z_min >= m_z_min && new_x_max <= m_x_max &&
54  new_y_max <= m_y_max && new_z_max <= m_z_max)
55  return;
56 
57  if (new_x_min > m_x_min) new_x_min = m_x_min;
58  if (new_x_max < m_x_max) new_x_max = m_x_max;
59  if (new_y_min > m_y_min) new_y_min = m_y_min;
60  if (new_y_max < m_y_max) new_y_max = m_y_max;
61  if (new_z_min > m_z_min) new_z_min = m_z_min;
62  if (new_z_max < m_z_max) new_z_max = m_z_max;
63 
64  // Additional margin:
65  if (additionalMarginMeters > 0)
66  {
67  if (new_x_min < m_x_min)
68  new_x_min = floor(new_x_min - additionalMarginMeters);
69  if (new_x_max > m_x_max)
70  new_x_max = ceil(new_x_max + additionalMarginMeters);
71  if (new_y_min < m_y_min)
72  new_y_min = floor(new_y_min - additionalMarginMeters);
73  if (new_y_max > m_y_max)
74  new_y_max = ceil(new_y_max + additionalMarginMeters);
75  if (new_z_min < m_z_min)
76  new_z_min = floor(new_z_min - additionalMarginMeters);
77  if (new_z_max > m_z_max)
78  new_z_max = ceil(new_z_max + additionalMarginMeters);
79  }
80 
81  // Adjust sizes to adapt them to full sized cells acording to the
82  // resolution:
83  if (fabs(
84  new_x_min / m_resolution_xy -
85  round(new_x_min / m_resolution_xy)) > 0.05)
86  new_x_min = m_resolution_xy * round(new_x_min / m_resolution_xy);
87  if (fabs(
88  new_y_min / m_resolution_xy -
89  round(new_y_min / m_resolution_xy)) > 0.05)
90  new_y_min = m_resolution_xy * round(new_y_min / m_resolution_xy);
91  if (fabs(
92  new_z_min / m_resolution_z -
93  round(new_z_min / m_resolution_z)) > 0.05)
94  new_z_min = m_resolution_z * round(new_z_min / m_resolution_z);
95  if (fabs(
96  new_x_max / m_resolution_xy -
97  round(new_x_max / m_resolution_xy)) > 0.05)
98  new_x_max = m_resolution_xy * round(new_x_max / m_resolution_xy);
99  if (fabs(
100  new_y_max / m_resolution_xy -
101  round(new_y_max / m_resolution_xy)) > 0.05)
102  new_y_max = m_resolution_xy * round(new_y_max / m_resolution_xy);
103  if (fabs(
104  new_z_max / m_resolution_z -
105  round(new_z_max / m_resolution_z)) > 0.05)
106  new_z_max = m_resolution_z * round(new_z_max / m_resolution_z);
107 
108  // Change the map size: Extensions at each side:
109  size_t extra_x_izq = round((m_x_min - new_x_min) / m_resolution_xy);
110  size_t extra_y_arr = round((m_y_min - new_y_min) / m_resolution_xy);
111  size_t extra_z_top = round((m_z_min - new_z_min) / m_resolution_z);
112 
113  size_t new_size_x = round((new_x_max - new_x_min) / m_resolution_xy);
114  size_t new_size_y = round((new_y_max - new_y_min) / m_resolution_xy);
115  size_t new_size_z = round((new_z_max - new_z_min) / m_resolution_z);
116  size_t new_size_x_times_y = new_size_x * new_size_y;
117 
118  // Reserve new memory:
119  typename std::vector<T> new_map;
120  new_map.resize(
121  new_size_x * new_size_y * new_size_z, defaultValueNewCells);
122 
123  // Copy previous rows:
124  size_t x, y, z;
125  typename std::vector<T>::iterator itSrc, itDst;
126  for (z = 0; z < m_size_z; z++)
127  {
128  for (y = 0; y < m_size_y; y++)
129  {
130  for (x = 0,
131  itSrc =
132  (m_map.begin() + y * m_size_x + z * m_size_x_times_y),
133  itDst =
134  (new_map.begin() + extra_x_izq +
135  (y + extra_y_arr) * new_size_x +
136  (z + extra_z_top) * new_size_x_times_y);
137  x < m_size_x; ++x, ++itSrc, ++itDst)
138  {
139  *itDst = *itSrc;
140  }
141  }
142  }
143 
144  // Update the new map limits:
145  m_x_min = new_x_min;
146  m_x_max = new_x_max;
147  m_y_min = new_y_min;
148  m_y_max = new_y_max;
149  m_z_min = new_z_min;
150  m_z_max = new_z_max;
151 
152  m_size_x = new_size_x;
153  m_size_y = new_size_y;
154  m_size_z = new_size_z;
155  m_size_x_times_y = new_size_x_times_y;
156 
157  // Keep the new map only:
158  m_map.swap(new_map);
159  }
160 
161  /** Changes the size of the grid, ERASING all previous contents.
162  * If \a fill_value is left as nullptr, the contents of cells may be
163  * undefined (some will remain with
164  * their old values, the new ones will have the default voxel value, but
165  * the location of old values
166  * may change wrt their old places).
167  * If \a fill_value is not nullptr, it is assured that all cells will have
168  * a copy of that value after resizing.
169  * If `resolution_z`<0, the same resolution will be used for all dimensions
170  * x,y,z as given in `resolution_xy`
171  * \sa resize, fill
172  */
173  virtual void setSize(
174  const double x_min, const double x_max, const double y_min,
175  const double y_max, const double z_min, const double z_max,
176  const double resolution_xy, const double resolution_z_ = -1.0,
177  const T* fill_value = nullptr)
178  {
179  const double resolution_z =
180  resolution_z_ > 0.0 ? resolution_z_ : resolution_xy;
181 
182  // Adjust sizes to adapt them to full sized cells acording to the
183  // resolution:
184  m_x_min = x_min;
185  m_y_min = y_min;
186  m_z_min = z_min;
187 
188  m_x_max =
189  x_min + resolution_xy * round((x_max - x_min) / resolution_xy);
190  m_y_max =
191  y_min + resolution_xy * round((y_max - y_min) / resolution_xy);
192  m_z_max = z_min + resolution_z * round((z_max - z_min) / resolution_z);
193 
194  // Res:
195  m_resolution_xy = resolution_xy;
196  m_resolution_z = resolution_z;
197 
198  // Now the number of cells should be integers:
203 
204  // Cells memory:
205  if (fill_value)
206  m_map.assign(m_size_x * m_size_y * m_size_z, *fill_value);
207  else
208  m_map.resize(m_size_x * m_size_y * m_size_z);
209  }
210 
211  /** Erase the contents of all the cells, setting them to their default
212  * values (default ctor). */
213  virtual void clear()
214  {
215  m_map.clear();
216  m_map.resize(m_size_x * m_size_y * m_size_z);
217  }
218 
219  /** Fills all the cells with the same value
220  */
221  inline void fill(const T& value)
222  {
223  for (typename std::vector<T>::iterator it = m_map.begin();
224  it != m_map.end(); ++it)
225  *it = value;
226  }
227 
228  static const size_t INVALID_VOXEL_IDX = size_t(-1);
229 
230  /** Gets the absolute index of a voxel in the linear container m_map[] from
231  * its cx,cy,cz indices, or -1 if out of map bounds (in any dimension). \sa
232  * x2idx(), y2idx(), z2idx() */
233  inline size_t cellAbsIndexFromCXCYCZ(
234  const int cx, const int cy, const int cz) const
235  {
236  if (cx < 0 || cx >= static_cast<int>(m_size_x))
237  return INVALID_VOXEL_IDX;
238  if (cy < 0 || cy >= static_cast<int>(m_size_y))
239  return INVALID_VOXEL_IDX;
240  if (cz < 0 || cz >= static_cast<int>(m_size_z))
241  return INVALID_VOXEL_IDX;
242  return cx + cy * m_size_x + cz * m_size_x_times_y;
243  }
244 
245  /** Returns a pointer to the contents of a voxel given by its coordinates,
246  * or nullptr if it is out of the map extensions.
247  */
248  inline T* cellByPos(double x, double y, double z)
249  {
250  const size_t cidx =
252  if (cidx == INVALID_VOXEL_IDX) return nullptr;
253  return &m_map[cidx];
254  }
255  /** \overload */
256  inline const T* cellByPos(double x, double y, double z) const
257  {
258  const size_t cidx =
260  if (cidx == INVALID_VOXEL_IDX) return nullptr;
261  return &m_map[cidx];
262  }
263 
264  /** Returns a pointer to the contents of a voxel given by its voxel indexes,
265  * or nullptr if it is out of the map extensions.
266  */
267  inline T* cellByIndex(unsigned int cx, unsigned int cy, unsigned int cz)
268  {
269  const size_t cidx = cellAbsIndexFromCXCYCZ(cx, cy, cz);
270  if (cidx == INVALID_VOXEL_IDX) return nullptr;
271  return &m_map[cidx];
272  }
273 
274  /** Returns a pointer to the contents of a voxel given by its voxel indexes,
275  * or nullptr if it is out of the map extensions.
276  */
277  inline const T* cellByIndex(
278  unsigned int cx, unsigned int cy, unsigned int cz) const
279  {
280  const size_t cidx = cellAbsIndexFromCXCYCZ(cx, cy, cz);
281  if (cidx == INVALID_VOXEL_IDX) return nullptr;
282  return &m_map[cidx];
283  }
284 
285  inline size_t getSizeX() const { return m_size_x; }
286  inline size_t getSizeY() const { return m_size_y; }
287  inline size_t getSizeZ() const { return m_size_z; }
288  inline size_t getVoxelCount() const { return m_size_x_times_y * m_size_z; }
289  inline double getXMin() const { return m_x_min; }
290  inline double getXMax() const { return m_x_max; }
291  inline double getYMin() const { return m_y_min; }
292  inline double getYMax() const { return m_y_max; }
293  inline double getZMin() const { return m_z_min; }
294  inline double getZMax() const { return m_z_max; }
295  inline double getResolutionXY() const { return m_resolution_xy; }
296  inline double getResolutionZ() const { return m_resolution_z; }
297  /** Transform a coordinate values into voxel indexes */
298  inline int x2idx(double x) const
299  {
300  return static_cast<int>((x - m_x_min) / m_resolution_xy);
301  }
302  inline int y2idx(double y) const
303  {
304  return static_cast<int>((y - m_y_min) / m_resolution_xy);
305  }
306  inline int z2idx(double z) const
307  {
308  return static_cast<int>((z - m_z_min) / m_resolution_z);
309  }
310 
311  /** Transform a voxel index into a coordinate value of the voxel central
312  * point */
313  inline double idx2x(int cx) const { return m_x_min + (cx)*m_resolution_xy; }
314  inline double idx2y(int cy) const { return m_y_min + (cy)*m_resolution_xy; }
315  inline double idx2z(int cz) const { return m_z_min + (cz)*m_resolution_z; }
316  protected:
317  /** The cells */
318  mutable std::vector<T> m_map;
319  /** Used only from logically const method that really need to modify the
320  * object */
321  inline std::vector<T>& m_map_castaway_const() const { return m_map; }
325  /** Serialization of all parameters, except the contents of each voxel
326  * (responsability of the derived class) */
328  {
329  out << m_x_min << m_x_max << m_y_min << m_y_max << m_z_min << m_z_max;
331  out << static_cast<uint32_t>(m_size_x)
332  << static_cast<uint32_t>(m_size_y)
333  << static_cast<uint32_t>(m_size_z);
334  }
335  /** Serialization of all parameters, except the contents of each voxel
336  * (responsability of the derived class) */
338  {
339  in >> m_x_min >> m_x_max >> m_y_min >> m_y_max >> m_z_min >> m_z_max;
341 
342  uint32_t nX, nY, nZ;
343  in >> nX >> nY >> nZ;
344  m_size_x = nX;
345  m_size_y = nY;
346  m_size_z = nZ;
347  m_map.resize(nX * nY * nZ);
348  }
349 
350 }; // end of CDynamicGrid3D<>
351 
352 } // End of namespace
353 } // end of namespace
int z2idx(double z) const
T * cellByPos(double x, double y, double z)
Returns a pointer to the contents of a voxel given by its coordinates, or nullptr if it is out of the...
GLdouble GLdouble z
Definition: glext.h:3872
std::vector< T > m_map
The cells.
size_t cellAbsIndexFromCXCYCZ(const int cx, const int cy, const int cz) const
Gets the absolute index of a voxel in the linear container m_map[] from its cx,cy,cz indices, or -1 if out of map bounds (in any dimension).
const T * cellByPos(double x, double y, double z) const
CDynamicGrid3D(double x_min=-1.0, double x_max=1.0, double y_min=-1.0, double y_max=+1.0, double z_min=-1.0, double z_max=1.0, double resolution_xy=0.5, double resolution_z=0.5)
Constructor.
double idx2z(int cz) const
static const size_t INVALID_VOXEL_IDX
Scalar * iterator
Definition: eigen_plugins.h:26
void dyngridcommon_writeToStream(mrpt::utils::CStream &out) const
Serialization of all parameters, except the contents of each voxel (responsability of the derived cla...
virtual void clear()
Erase the contents of all the cells, setting them to their default values (default ctor)...
A 3D rectangular grid of dynamic size which stores any kind of data at each voxel.
const T * cellByIndex(unsigned int cx, unsigned int cy, unsigned int cz) const
Returns a pointer to the contents of a voxel given by its voxel indexes, or nullptr if it is out of t...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
T * cellByIndex(unsigned int cx, unsigned int cy, unsigned int cz)
Returns a pointer to the contents of a voxel given by its voxel indexes, or nullptr if it is out of t...
virtual void resize(double new_x_min, double new_x_max, double new_y_min, double new_y_max, double new_z_min, double new_z_max, const T &defaultValueNewCells, double additionalMarginMeters=2.0)
Changes the size of the grid, maintaining previous contents.
virtual void setSize(const double x_min, const double x_max, const double y_min, const double y_max, const double z_min, const double z_max, const double resolution_xy, const double resolution_z_=-1.0, const T *fill_value=nullptr)
Changes the size of the grid, ERASING all previous contents.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
int x2idx(double x) const
Transform a coordinate values into voxel indexes.
void fill(const T &value)
Fills all the cells with the same value.
double idx2x(int cx) const
Transform a voxel index into a coordinate value of the voxel central point.
double idx2y(int cy) const
void dyngridcommon_readFromStream(mrpt::utils::CStream &in)
Serialization of all parameters, except the contents of each voxel (responsability of the derived cla...
GLuint in
Definition: glext.h:7274
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:25
GLenum GLint GLint y
Definition: glext.h:3538
GLsizei const GLfloat * value
Definition: glext.h:4117
std::vector< T > & m_map_castaway_const() const
Used only from logically const method that really need to modify the object.
GLenum GLint x
Definition: glext.h:3538
unsigned __int32 uint32_t
Definition: rptypes.h:47
int y2idx(double y) const



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