regular_squares_grid.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_CORE_REGULAR_SQUARES_GRID_H
2 #define SLAM_CTOR_CORE_REGULAR_SQUARES_GRID_H
3 
4 #include <cmath>
5 #include <cassert>
6 #include <utility>
7 #include <vector>
8 #include <limits>
9 
10 #include "../math_utils.h"
11 #include "../geometry_utils.h"
12 
14 public:
16  static constexpr double Dbl_Inf = std::numeric_limits<double>::infinity();
17 public:
18 
19  RegularSquaresGrid(int w, int h, double scale) :
20  _width{w}, _height{h}, _m_per_cell(scale) {}
21 
22  RegularSquaresGrid(const RegularSquaresGrid &grid) = default;
23  RegularSquaresGrid& operator=(const RegularSquaresGrid &grid) = default;
24  RegularSquaresGrid(RegularSquaresGrid &&grid) = default;
26  virtual ~RegularSquaresGrid() = default;
27 
28  // TODO: change return type to unsigned
29  virtual int width() const { return _width; }
30  virtual int height() const { return _height; }
31  virtual double scale() const { return _m_per_cell; }
32  virtual void rescale(double /*cell_size*/) {}
33 
34  Coord world_to_cell(const Point2D &pt) const {
35  return world_to_cell(pt.x, pt.y);
36  }
37 
38  // FIXME: code duplication for perfromance reasons.
39  // Find out the reason why world_to_cell(x, y, scale) runs slower
40  Coord world_to_cell(double x, double y) const {
41  // TODO: handle infinity
42  assert(x != Dbl_Inf && y != Dbl_Inf);
43 
44  auto curr_scale = scale();
45  return {int(std::floor(x / curr_scale)), int(std::floor(y / curr_scale))};
46  }
47 
48  Coord world_to_cell(double x, double y, double scale) const {
49  // TODO: handle infinity
50  assert(x != Dbl_Inf && y != Dbl_Inf);
51 
52  return {int(std::floor(x / scale)), int(std::floor(y / scale))};
53  }
54 
55  // TODO: move resterization to a separate component
56  std::vector<Coord> world_to_cells(const Segment2D &s) const {
57  // returns a vector of cells intersected by a given segment.
58  // The first cell contains start of the segment, the last - its end.
59  // algorithm: modified 4-connection line
60  double d_x = s.end().x - s.beg().x, d_y = s.end().y - s.beg().y;
61  int inc_x = 0 < d_x ? 1 : -1, inc_y = 0 < d_y ? 1 : -1;
62 
63  Coord pnt = world_to_cell(s.beg());
64  const Coord end = world_to_cell(s.end());
65  size_t cells_nm = std::abs(end.x - pnt.x) + std::abs(end.y - pnt.y) + 1;
66  std::vector<Coord> cells;
67  cells.reserve(cells_nm);
68 
69  double m_per_cell = scale();
70  Point2D mid_cell{(pnt.x + 0.5) * m_per_cell, (pnt.y + 0.5) * m_per_cell};
71  // NB: y's are multiplied by d_x to eliminate separate vert. line handling
72  auto mid_cell_seg_y = d_x * s.beg().y + (mid_cell.x - s.beg().x) * d_y;
73  auto e = mid_cell_seg_y - mid_cell.y * d_x; // e = actual_e * d_x
74  auto e_x_inc = inc_x * m_per_cell * d_y; // slope * d_x
75  auto e_y_inc = -inc_y * m_per_cell * d_x; // - d_x
76 
77  while (1) {
78  cells.push_back(pnt);
79  if (pnt == end) { break; }
80  if (cells_nm < cells.size()) { // fail-over (fp rounding errors)
81  return DiscreteSegment2D{world_to_cell(s.beg()), end};
82  }
83 
84  double e_x = e + e_x_inc, e_y = e + e_y_inc;
85  double abs_err_diff = std::abs(e_y) - std::abs(e_x);
86  if (are_equal(abs_err_diff, 0)) {
87  // through cell diagonal or coord grid's line aligned
88  if (pnt.x == end.x) { pnt.y += inc_y; }
89  else if (pnt.y == end.y) { pnt.x += inc_x; }
90  else { pnt.x += inc_x; pnt.y += inc_y; }
91  e = 0;
92  } else if (0 < abs_err_diff) {
93  pnt.x += inc_x;
94  e = e_x;
95  } else { // abs_err_diff < 0
96  pnt.y += inc_y;
97  e = e_y;
98  }
99  }
100  return cells;
101  }
102 
103  Point2D cell_to_world(const Coord &cell) const {
104  return {scale() * (cell.x + 0.5), scale() * (cell.y + 0.5)};
105  }
106 
107  // TODO: consider renaming ~"occupied_space"
108  Rectangle world_cell_bounds(const Coord &coord) const {
109  auto m_per_cell = scale();
110  if (m_per_cell == Dbl_Inf) {
111  return {-Dbl_Inf, Dbl_Inf, -Dbl_Inf, Dbl_Inf};
112  }
113 
114  return {m_per_cell * coord.y, // bot
115  m_per_cell * (coord.y + 1), // top
116  m_per_cell * coord.x, // left
117  m_per_cell * (coord.x + 1)}; // right
118  }
119 
120  virtual DiscretePoint2D origin() const {
121  return DiscretePoint2D{(int)width() / 2, (int)height() / 2};
122  }
123 
124  virtual bool has_cell(const Coord &c) const {
126  }
127 
128  Coord internal2external(const Coord &coord) const {
129  return coord - origin();
130  }
131 
132 protected:
133 
134  bool has_internal_cell(const Coord &c) const {
135  return (0 <= c.x && c.x < width()) and (0 <= c.y && c.y < height());
136  }
137 
138  // A cell coordinate determined outside of the map to the coord on the grid
139  // Motivation: grid's structure changes after world_to_cell coord return
140  // can spoil the returned coord.
141  Coord external2internal(const Coord &coord) const {
142  return coord + origin();
143  }
144 
145  // notifies with actual height/width changes
146  void set_height(unsigned h) { _height = h; }
147  void set_width(unsigned w) { _width = w; }
148  void set_scale(double s) { _m_per_cell = s; }
149 
150 private: // fields
152  double _m_per_cell;
153 };
154 
155 #endif
Coord external2internal(const Coord &coord) const
static constexpr double Dbl_Inf
Coord world_to_cell(const Point2D &pt) const
Rectangle world_cell_bounds(const Coord &coord) const
CONSTEXPR bool are_equal(const T &a, const T &b, const T &eps)
Definition: math_utils.h:17
Point2D cell_to_world(const Coord &cell) const
virtual bool has_cell(const Coord &c) const
void set_width(unsigned w)
virtual DiscretePoint2D origin() const
bool has_internal_cell(const Coord &c) const
virtual ~RegularSquaresGrid()=default
Coord world_to_cell(double x, double y, double scale) const
const Point2D & end() const
void set_height(unsigned h)
RegularSquaresGrid & operator=(const RegularSquaresGrid &grid)=default
Coord internal2external(const Coord &coord) const
std::vector< Coord > world_to_cells(const Segment2D &s) const
virtual int height() const
const Point2D & beg() const
Coord world_to_cell(double x, double y) const
virtual void rescale(double)
RegularSquaresGrid(int w, int h, double scale)
virtual double scale() const
virtual int width() const


slam_constructor
Author(s): JetBrains Research, OSLL team
autogenerated on Mon Jun 10 2019 15:08:25