00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CDynamicGrid_H
00029 #define CDynamicGrid_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032
00033 namespace mrpt
00034 {
00035 namespace utils
00036 {
00037 using namespace mrpt::system;
00038
00039
00040
00041
00042
00043 template <class T>
00044 class CDynamicGrid
00045 {
00046 protected:
00047
00048
00049 std::vector<T> m_map;
00050
00051
00052 inline std::vector<T> & m_map_castaway_const() const { return const_cast< std::vector<T>& >( m_map ); }
00053
00054 float m_x_min,m_x_max,m_y_min,m_y_max;
00055 float m_resolution;
00056 size_t m_size_x, m_size_y;
00057
00058 public:
00059
00060
00061 CDynamicGrid( float x_min = -10.0f,
00062 float x_max = 10.0f,
00063 float y_min = -10.0f,
00064 float y_max = 10.0f,
00065 float resolution = 0.10f) :
00066 m_map(),
00067 m_x_min(),m_x_max(),m_y_min(),m_y_max(),
00068 m_resolution(),
00069 m_size_x(), m_size_y()
00070 {
00071 setSize(x_min,x_max,y_min,y_max,resolution);
00072 }
00073
00074
00075
00076 virtual ~CDynamicGrid()
00077 {
00078 }
00079
00080
00081
00082
00083 void setSize( float x_min,
00084 float x_max,
00085 float y_min,
00086 float y_max,
00087 float resolution )
00088 {
00089
00090 m_x_min = resolution*round(x_min/resolution);
00091 m_y_min = resolution*round(y_min/resolution);
00092 m_x_max = resolution*round(x_max/resolution);
00093 m_y_max = resolution*round(y_max/resolution);
00094
00095
00096 m_resolution = resolution;
00097
00098
00099 m_size_x = round((m_x_max-m_x_min)/m_resolution);
00100 m_size_y = round((m_y_max-m_y_min)/m_resolution);
00101
00102
00103 m_map.resize(m_size_x*m_size_y);
00104 }
00105
00106
00107
00108 void clear()
00109 {
00110 m_map.clear();
00111 m_map.resize(m_size_x*m_size_y);
00112 }
00113
00114
00115
00116 inline void fill( const T& value ) { std::fill(m_map.begin(),m_map.end(),value); }
00117
00118
00119
00120
00121 virtual void resize(
00122 float new_x_min,
00123 float new_x_max,
00124 float new_y_min,
00125 float new_y_max,
00126 const T& defaultValueNewCells,
00127 float additionalMarginMeters = 2.0f )
00128 {
00129 MRPT_START
00130
00131 MRPT_CHECK_NORMAL_NUMBER(new_x_min)
00132 MRPT_CHECK_NORMAL_NUMBER(new_x_max)
00133 MRPT_CHECK_NORMAL_NUMBER(new_y_min)
00134 MRPT_CHECK_NORMAL_NUMBER(new_y_max)
00135
00136 unsigned int x,y;
00137 unsigned int extra_x_izq,extra_y_arr,new_size_x=0,new_size_y=0;
00138 typename std::vector<T> new_map;
00139 typename std::vector<T>::iterator itSrc,itDst;
00140
00141
00142 if (new_x_min>=m_x_min &&
00143 new_y_min>=m_y_min &&
00144 new_x_max<=m_x_max &&
00145 new_y_max<=m_y_max) return;
00146
00147 if (new_x_min>m_x_min) new_x_min=m_x_min;
00148 if (new_x_max<m_x_max) new_x_max=m_x_max;
00149 if (new_y_min>m_y_min) new_y_min=m_y_min;
00150 if (new_y_max<m_y_max) new_y_max=m_y_max;
00151
00152
00153 if (additionalMarginMeters>0)
00154 {
00155 if (new_x_min<m_x_min) new_x_min= floor(new_x_min-additionalMarginMeters);
00156 if (new_x_max>m_x_max) new_x_max= ceil(new_x_max+additionalMarginMeters);
00157 if (new_y_min<m_y_min) new_y_min= floor(new_y_min-additionalMarginMeters);
00158 if (new_y_max>m_y_max) new_y_max= ceil(new_y_max+additionalMarginMeters);
00159 }
00160
00161
00162 if (fabs(new_x_min/m_resolution - round(new_x_min/m_resolution))>0.05f )
00163 new_x_min = m_resolution*round(new_x_min/m_resolution);
00164 if (fabs(new_y_min/m_resolution - round(new_y_min/m_resolution))>0.05f )
00165 new_y_min = m_resolution*round(new_y_min/m_resolution);
00166 if (fabs(new_x_max/m_resolution - round(new_x_max/m_resolution))>0.05f )
00167 new_x_max = m_resolution*round(new_x_max/m_resolution);
00168 if (fabs(new_y_max/m_resolution - round(new_y_max/m_resolution))>0.05f )
00169 new_y_max = m_resolution*round(new_y_max/m_resolution);
00170
00171
00172 extra_x_izq = round((m_x_min-new_x_min) / m_resolution);
00173 extra_y_arr = round((m_y_min-new_y_min) / m_resolution);
00174
00175 new_size_x = round((new_x_max-new_x_min) / m_resolution);
00176 new_size_y = round((new_y_max-new_y_min) / m_resolution);
00177
00178
00179 new_map.resize(new_size_x*new_size_y,defaultValueNewCells);
00180
00181
00182 for (y=0;y<m_size_y;y++)
00183 {
00184 for (x=0,itSrc=(m_map.begin()+y*m_size_x),itDst=(new_map.begin()+extra_x_izq + (y+extra_y_arr)*new_size_x);
00185 x<m_size_x;
00186 x++,itSrc++,itDst++)
00187 {
00188 *itDst = *itSrc;
00189 }
00190 }
00191
00192
00193 m_x_min = new_x_min;
00194 m_x_max = new_x_max;
00195 m_y_min = new_y_min;
00196 m_y_max = new_y_max;
00197
00198 m_size_x = new_size_x;
00199 m_size_y = new_size_y;
00200
00201
00202 m_map.swap(new_map);
00203
00204 MRPT_END
00205
00206 }
00207
00208
00209
00210 inline T* cellByPos( float x, float y )
00211 {
00212 int cx = x2idx(x);
00213 int cy = y2idx(y);
00214
00215 if( cx<0 || cx>=static_cast<int>(m_size_x) ) return NULL;
00216 if( cy<0 || cy>=static_cast<int>(m_size_y) ) return NULL;
00217
00218 return &m_map[ cx + cy*m_size_x ];
00219 }
00220
00221
00222
00223 inline const T* cellByPos( float x, float y ) const
00224 {
00225 int cx = x2idx(x);
00226 int cy = y2idx(y);
00227
00228 if( cx<0 || cx>=static_cast<int>(m_size_x) ) return NULL;
00229 if( cy<0 || cy>=static_cast<int>(m_size_y) ) return NULL;
00230
00231 return &m_map[ cx + cy*m_size_x ];
00232 }
00233
00234
00235
00236 inline T* cellByIndex( unsigned int cx, unsigned int cy )
00237 {
00238 if( cx>=m_size_x || cy>=m_size_y)
00239 return NULL;
00240 else return &m_map[ cx + cy*m_size_x ];
00241 }
00242
00243
00244
00245 inline const T* cellByIndex( unsigned int cx, unsigned int cy ) const
00246 {
00247 if( cx>=m_size_x || cy>=m_size_y)
00248 return NULL;
00249 else return &m_map[ cx + cy*m_size_x ];
00250 }
00251
00252
00253
00254 inline size_t getSizeX() const { return m_size_x; }
00255
00256
00257
00258 inline size_t getSizeY() const { return m_size_y; }
00259
00260
00261
00262 inline float getXMin()const { return m_x_min; }
00263
00264
00265
00266 inline float getXMax()const { return m_x_max; }
00267
00268
00269
00270 inline float getYMin()const { return m_y_min; }
00271
00272
00273
00274 inline float getYMax()const { return m_y_max; }
00275
00276
00277
00278 inline float getResolution()const { return m_resolution; }
00279
00280
00281 virtual float cell2float(const T& c) const
00282 {
00283 return 0;
00284 }
00285
00286 void saveToTextFile(const std::string &fileName) const
00287 {
00288 FILE *f=os::fopen(fileName.c_str(),"wt");
00289 if(!f) return;
00290 for (unsigned int cy=0;cy<m_size_y;cy++)
00291 {
00292 for (unsigned int cx=0;cx<m_size_x;cx++)
00293 os::fprintf(f,"%f ",cell2float(m_map[ cx + cy*m_size_x ]));
00294 os::fprintf(f,"\n");
00295 }
00296 os::fclose(f);
00297 }
00298
00299
00300
00301 inline int x2idx(float x) const { return static_cast<int>( (x-m_x_min)/m_resolution ); }
00302 inline int y2idx(float y) const { return static_cast<int>( (y-m_y_min)/m_resolution ); }
00303 inline int xy2idx(float x,float y) const { return x2idx(x) + y2idx(y)*m_size_x; }
00304
00305
00306 inline void idx2cxcy(const int &idx, int &cx, int &cy ) const
00307 {
00308 cx = idx % m_size_x;
00309 cy = idx / m_size_x;
00310 }
00311
00312
00313
00314 inline float idx2x(int cx) const { return m_x_min+(cx+0.5f)*m_resolution; }
00315 inline float idx2y(int cy) const { return m_y_min+(cy+0.5f)*m_resolution; }
00316
00317
00318
00319 inline int x2idx(float x,float x_min) const { return static_cast<int>((x-m_x_min)/m_resolution ); }
00320 inline int y2idx(float y, float y_min) const { return static_cast<int>((y-m_y_min)/m_resolution ); }
00321
00322
00323
00324
00325
00326
00327
00328 template <class MAT>
00329 void getAsMatrix(MAT &m) const
00330 {
00331 m.setSize(m_size_y, m_size_x);
00332 if (m_map.empty()) return;
00333 const T* c = &m_map[0];
00334 for (size_t cy=0;cy<m_size_y;cy++)
00335 for (size_t cx=0;cx<m_size_x;cx++)
00336 m.set_unsafe(cy,cx, *c++);
00337 }
00338
00339 };
00340
00341 }
00342 }
00343 #endif