Grid.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2011, SRI International (R)
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #pragma once
19 
20 #ifndef __OpenKarto_Grid_h__
21 #define __OpenKarto_Grid_h__
22 
23 #include <OpenKarto/Object.h>
25 
26 namespace karto
27 {
28 
30 
31 
35 
40  {
41  public:
45  virtual void operator() (kt_int32u) {};
46  }; // Functor
47 
51 
55  template<typename T>
56  class Grid : public Object
57  {
58  KARTO_RTTI();
59 
60  public:
68  static Grid* CreateGrid(kt_int32s width, kt_int32s height, kt_double resolution)
69  {
70  Grid* pGrid = new Grid(width, height);
71 
72  pGrid->GetCoordinateConverter()->SetScale(1.0 / resolution);
73 
74  return pGrid;
75  }
76 
77  protected:
78  //@cond EXCLUDE
82  virtual ~Grid()
83  {
84  delete [] m_pData;
85  delete m_pCoordinateConverter;
86  }
87  //@endcond
88 
89  public:
93  void Clear()
94  {
95  memset(m_pData, 0, GetDataSize() * sizeof(T));
96  }
97 
103  {
104  Grid* pGrid = CreateGrid(GetWidth(), GetHeight(), GetResolution());
105  pGrid->GetCoordinateConverter()->SetOffset(GetCoordinateConverter()->GetOffset());
106 
107  memcpy(pGrid->GetDataPointer(), GetDataPointer(), GetDataSize());
108 
109  return pGrid;
110  }
111 
117  virtual void Resize(kt_int32s width, kt_int32s height)
118  {
119  m_Width = width;
120  m_Height = height;
121  m_WidthStep = math::AlignValue<kt_int32s>(width, 8);
122 
123  if (m_pData != NULL)
124  {
125  delete[] m_pData;
126  m_pData = NULL;
127  }
128 
129  try
130  {
131  m_pData = new T[GetDataSize()];
132 
133  if (m_pCoordinateConverter == NULL)
134  {
135  m_pCoordinateConverter = new CoordinateConverter();
136  }
137 
138  m_pCoordinateConverter->SetSize(Size2<kt_int32s>(width, height));
139  }
140  catch (...)
141  {
142  m_pData = NULL;
143 
144  m_Width = 0;
145  m_Height = 0;
146  m_WidthStep = 0;
147  }
148 
149  Clear();
150  }
151 
157  inline kt_bool IsValidGridIndex(const Vector2i& rGrid) const
158  {
159  return (math::IsUpTo(rGrid.GetX(), GetWidth()) && math::IsUpTo(rGrid.GetY(), GetHeight()));
160  }
161 
169  virtual kt_int32s GridIndex(const Vector2i& rGrid, kt_bool boundaryCheck = true) const
170  {
171  if (boundaryCheck == true)
172  {
173  if (IsValidGridIndex(rGrid) == false)
174  {
175  StringBuilder errorMessage;
176  errorMessage << "Index (" << rGrid.GetX() << ", " << rGrid.GetY() << ")" << " out of range. Index must be between [0; " << GetWidth() << ") and [0; " << GetHeight() << ")";
177  throw Exception(errorMessage.ToString());
178  }
179  }
180 
181  kt_int32s index = rGrid.GetX() + (rGrid.GetY() * m_WidthStep);
182 
183  if (boundaryCheck == true)
184  {
185  assert(math::IsUpTo(index, GetDataSize()));
186  }
187 
188  return index;
189  }
190 
197  {
198  Vector2i grid;
199 
200  grid.SetY(index / m_WidthStep);
201  grid.SetX(index - grid.GetY() * m_WidthStep);
202 
203  return grid;
204  }
205 
212  inline Vector2i WorldToGrid(const Vector2d& rWorld, kt_bool flipY = false) const
213  {
214  return GetCoordinateConverter()->WorldToGrid(rWorld, flipY);
215  }
216 
223  inline Vector2d GridToWorld(const Vector2i& rGrid, kt_bool flipY = false) const
224  {
225  return GetCoordinateConverter()->GridToWorld(rGrid, flipY);
226  }
227 
233  T* GetDataPointer(const Vector2i& rGrid)
234  {
235  kt_int32s index = GridIndex(rGrid, true);
236  return m_pData + index;
237  }
238 
244  T* GetDataPointer(const Vector2i& rGrid) const
245  {
246  kt_int32s index = GridIndex(rGrid, true);
247  return m_pData + index;
248  }
249 
254  inline kt_int32s GetWidth() const
255  {
256  return m_Width;
257  };
258 
263  inline kt_int32s GetHeight() const
264  {
265  return m_Height;
266  };
267 
272  inline const Size2<kt_int32s> GetSize() const
273  {
274  return Size2<kt_int32s>(GetWidth(), GetHeight());
275  }
276 
281  inline kt_int32s GetWidthStep() const
282  {
283  return m_WidthStep;
284  }
285 
290  inline T* GetDataPointer()
291  {
292  return m_pData;
293  }
294 
299  inline T* GetDataPointer() const
300  {
301  return m_pData;
302  }
303 
308  inline kt_int32s GetDataSize() const
309  {
310  return m_WidthStep * GetHeight();
311  }
312 
318  inline T GetValue(const Vector2i& rGrid) const
319  {
320  kt_int32s index = GridIndex(rGrid);
321  return m_pData[index];
322  }
323 
329  inline void SetValue(const Vector2i& rGrid, T rValue) const
330  {
331  kt_int32s index = GridIndex(rGrid);
332  m_pData[index] = rValue;
333  }
334 
340  {
341  return m_pCoordinateConverter;
342  }
343 
348  inline kt_double GetResolution() const
349  {
350  return GetCoordinateConverter()->GetResolution();
351  }
352 
358  {
359  return GetCoordinateConverter()->GetBoundingBox();
360  }
361 
371  void TraceLine(kt_int32s x0, kt_int32s y0, kt_int32s x1, kt_int32s y1, Functor* f = NULL)
372  {
373  kt_bool steep = abs(y1 - y0) > abs(x1 - x0);
374  if (steep)
375  {
376  math::Swap(x0, y0);
377  math::Swap(x1, y1);
378  }
379  if (x0 > x1)
380  {
381  math::Swap(x0, x1);
382  math::Swap(y0, y1);
383  }
384 
385  kt_int32s deltaX = x1 - x0;
386  kt_int32s deltaY = abs(y1 - y0);
387  kt_int32s error = 0;
388  kt_int32s ystep;
389  kt_int32s y = y0;
390 
391  if (y0 < y1)
392  {
393  ystep = 1;
394  }
395  else
396  {
397  ystep = -1;
398  }
399 
400  kt_int32s pointX;
401  kt_int32s pointY;
402  for (kt_int32s x = x0; x <= x1; x++)
403  {
404  if (steep)
405  {
406  pointX = y;
407  pointY = x;
408  }
409  else
410  {
411  pointX = x;
412  pointY = y;
413  }
414 
415  error += deltaY;
416 
417  if (2 * error >= deltaX)
418  {
419  y += ystep;
420  error -= deltaX;
421  }
422 
423  Vector2i gridIndex(pointX, pointY);
424  if (IsValidGridIndex(gridIndex))
425  {
426  kt_int32s index = GridIndex(gridIndex, false);
427  T* pGridPointer = GetDataPointer();
428  pGridPointer[index]++;
429 
430  if (f != NULL)
431  {
432  (*f)(index);
433  }
434  }
435  }
436  }
437 
438  protected:
444  Grid(kt_int32s width, kt_int32s height)
445  : m_Width(0)
446  , m_Height(0)
447  , m_WidthStep(0)
448  , m_pData(NULL)
449 
450  , m_pCoordinateConverter(NULL)
451  {
452  Resize(width, height);
453  }
454 
455  private:
456  Grid(const Grid&);
457  const Grid& operator=(const Grid&);
458 
459  private:
460  kt_int32s m_Width; // width of grid
461  kt_int32s m_Height; // height of grid
462  kt_int32s m_WidthStep; // 8-byte aligned width of grid
463  T* m_pData; // grid data
464 
465  CoordinateConverter* m_pCoordinateConverter; // coordinate converter to convert between world coordinates and grid coordinates
466  }; // Grid
467 
472 
477 
482 
487 
489 
490 }
491 
492 #endif // __OpenKarto_Grid_h__
kt_int32s GetHeight() const
Definition: Grid.h:263
bool kt_bool
Definition: Types.h:145
kt_int32s GetDataSize() const
Definition: Grid.h:308
const Size2< kt_int32s > GetSize() const
Definition: Grid.h:272
T * GetDataPointer() const
Definition: Grid.h:299
kt_int32s GetWidthStep() const
Definition: Grid.h:281
T GetValue(const Vector2i &rGrid) const
Definition: Grid.h:318
T * GetDataPointer(const Vector2i &rGrid) const
Definition: Grid.h:244
f
kt_bool IsValidGridIndex(const Vector2i &rGrid) const
Definition: Grid.h:157
const T & GetY() const
Definition: Geometry.h:369
#define KARTO_EXPORT
Definition: Macros.h:78
void SetValue(const Vector2i &rGrid, T rValue) const
Definition: Grid.h:329
void SetX(const T &x)
Definition: Geometry.h:360
BoundingBox2 GetBoundingBox() const
Definition: Grid.h:357
kt_bool IsUpTo(const T &value, const T &maximum)
Definition: Math.h:175
kt_int32s GetWidth() const
Definition: Grid.h:254
TFSIMD_FORCE_INLINE const tfScalar & y() const
virtual kt_int32s GridIndex(const Vector2i &rGrid, kt_bool boundaryCheck=true) const
Definition: Grid.h:169
void SetOffset(const Vector2d &rOffset)
kt_int32s m_Width
Definition: Grid.h:460
void Clear()
Definition: Grid.h:93
const T & GetX() const
Definition: Geometry.h:351
void SetScale(kt_double scale)
kt_int32s m_WidthStep
Definition: Grid.h:462
uint32_t kt_int32u
Definition: Types.h:111
void TraceLine(kt_int32s x0, kt_int32s y0, kt_int32s x1, kt_int32s y1, Functor *f=NULL)
Definition: Grid.h:371
Grid * Clone()
Definition: Grid.h:102
kt_double GetResolution() const
Definition: Grid.h:348
#define KARTO_RTTI()
Definition: Meta.h:198
virtual void Resize(kt_int32s width, kt_int32s height)
Definition: Grid.h:117
static Grid * CreateGrid(kt_int32s width, kt_int32s height, kt_double resolution)
Definition: Grid.h:68
Vector2d GridToWorld(const Vector2i &rGrid, kt_bool flipY=false) const
Definition: Grid.h:223
T * GetDataPointer()
Definition: Grid.h:290
TFSIMD_FORCE_INLINE const tfScalar & x() const
kt_int32s m_Height
Definition: Grid.h:461
const String & ToString() const
int32_t kt_int32s
Definition: Types.h:106
KARTO_TYPE(Grid< kt_int8u >)
CoordinateConverter * GetCoordinateConverter() const
Definition: Grid.h:339
double kt_double
Definition: Types.h:160
Vector2i WorldToGrid(const Vector2d &rWorld, kt_bool flipY=false) const
Definition: Grid.h:212
void Swap(T &x, T &y)
Definition: Math.h:286
CoordinateConverter * m_pCoordinateConverter
Definition: Grid.h:465
Vector2i IndexToGrid(kt_int32s index) const
Definition: Grid.h:196
Definition: Any.cpp:20
T * GetDataPointer(const Vector2i &rGrid)
Definition: Grid.h:233
void SetY(const T &y)
Definition: Geometry.h:378
T * m_pData
Definition: Grid.h:463
Grid(kt_int32s width, kt_int32s height)
Definition: Grid.h:444


nav2d_karto
Author(s): Sebastian Kasperski
autogenerated on Tue Nov 7 2017 06:02:36