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