geolib2
HeightMap.cpp
Go to the documentation of this file.
1 #include "geolib/HeightMap.h"
2 
3 #include <assert.h>
4 
5 namespace geo {
6 
7 HeightMap::HeightMap() : root_(0) {
8 }
9 
11  if (orig.root_) {
12  root_ = new HeightMapNode(*orig.root_);
13  } else {
14  root_ = 0;
15  }
16  mesh_ = orig.mesh_;
17 }
18 
20  delete root_;
21 }
22 
24  return new HeightMap(*this);
25 }
26 
27 bool HeightMap::intersect(const Ray& r, float t0, float t1, double& distance) const {
28  if (!root_) {
29  return false;
30  }
31  return root_->intersect(r, t0, t1, distance);
32 }
33 
34 HeightMap HeightMap::fromGrid(const std::vector<std::vector<double> >& grid, double resolution) {
35  unsigned int mx_max = grid.size();
36  unsigned int my_max = grid[0].size();
37 
38  unsigned int size = std::max(mx_max, my_max);
39 
40  unsigned int pow_size = 1;
41  while(pow_size < size) {
42  pow_size *= 2;
43  }
44 
45  std::vector<std::vector<double> > pow_grid(pow_size);
46 
47  for(unsigned int mx = 0; mx < mx_max; ++mx) {
48  pow_grid[mx].resize(pow_size, 0);
49  for(unsigned int my = 0; my < my_max; ++my) {
50  pow_grid[mx][my] = grid[mx][my];
51  }
52  }
53 
54  for(unsigned int mx = mx_max; mx < pow_size; ++mx) {
55  pow_grid[mx].resize(pow_size, 0);
56  }
57 
58  HeightMap hmap;
59  hmap.root_ = createQuadTree(pow_grid, 0, 0, pow_size, pow_size, resolution);
60 
61  // * * * * * * calculate mesh for rasterization * * * * * * * *
62 
63  std::vector<std::vector<bool> > visited_grid(grid.size());
64  for(unsigned int mx = 0; mx < mx_max; ++mx) {
65  visited_grid[mx].resize(my_max, false);
66  }
67 
68  // top triangles
69  for(unsigned int mx = 0; mx < mx_max; ++mx) {
70  for(unsigned int my = 0; my < my_max; ++my) {
71  double h = grid[mx][my];
72 
73  if (!visited_grid[mx][my] && h > 0) {
74  unsigned int max_x = mx_max;
75  unsigned int max_y = my;
76  for(unsigned int y2 = my; y2 < my_max && std::abs(grid[mx][y2] - h) < 1e-10; ++y2) {
77  for(unsigned int x2 = mx; x2 < max_x; ++x2) {
78  if (std::abs(grid[x2][y2] - h) > 1e-10) {
79  max_x = x2;
80  break;
81  }
82  }
83  ++max_y;
84  }
85 
86  for(unsigned int y2 = my; y2 < max_y; ++y2) {
87  for(unsigned int x2 = mx; x2 < max_x; ++x2) {
88  visited_grid[x2][y2] = true;
89  }
90  }
91 
92  int p0 = hmap.mesh_.addPoint(resolution * mx, resolution * my, h);
93  int p1 = hmap.mesh_.addPoint(resolution * max_x, resolution * my, h);
94  int p2 = hmap.mesh_.addPoint(resolution * mx, resolution * max_y, h);
95  int p3 = hmap.mesh_.addPoint(resolution * max_x, resolution * max_y, h);
96 
97  hmap.mesh_.addTriangle(p0, p1, p2);
98  hmap.mesh_.addTriangle(p1, p3, p2);
99  }
100  }
101  }
102 
103  // side triangles x-axis
104  for(unsigned int mx = 0; mx <= mx_max; ++mx) {
105 
106  double h_last = 0;
107  double h2_last = 0;
108  int my_start = -1;
109  for(unsigned int my = 0; my <= my_max; ++my) {
110  double h = 0;
111  if (mx < mx_max && my < my_max) {
112  h = grid[mx][my];
113  }
114 
115  double h2 = 0;
116  if (mx > 0 && my < my_max) {
117  h2 = grid[mx - 1][my];
118  }
119 
120  if (my_start >= 0) {
121  if (std::abs(h - h_last) + std::abs(h2 - h2_last) > 1e-10) {
122  // create triangles
123  int p0 = hmap.mesh_.addPoint(resolution * mx, resolution * my_start, h_last);
124  int p1 = hmap.mesh_.addPoint(resolution * mx, resolution * my, h_last);
125  int p2 = hmap.mesh_.addPoint(resolution * mx, resolution * my_start, h2_last);
126  int p3 = hmap.mesh_.addPoint(resolution * mx, resolution * my, h2_last);
127 
128  hmap.mesh_.addTriangle(p1, p2, p0);
129  hmap.mesh_.addTriangle(p2, p1, p3);
130 
131  if (std::abs(h - h2) > 1e-10) {
132  my_start = my;
133  } else {
134  my_start = -1;
135  }
136  }
137  } else if (std::abs(h - h2) > 1e-10) {
138  my_start = my;
139  }
140 
141  h_last = h;
142  h2_last = h2;
143  }
144  }
145 
146  // side triangles y-axis
147  for(unsigned int my = 0; my <= my_max; ++my) {
148  double h_last = 0;
149  double h2_last = 0;
150  int mx_start = -1;
151  for(unsigned int mx = 0; mx <= mx_max; ++mx) {
152  double h = 0;
153  if (mx < mx_max && my < my_max) {
154  h = grid[mx][my];
155  }
156 
157  double h2 = 0;
158  if (my > 0 && mx < mx_max) {
159  h2 = grid[mx][my - 1];
160  }
161 
162  if (mx_start >= 0) {
163  if (std::abs(h - h_last) + std::abs(h2 - h2_last) > 1e-10) {
164  // create triangles
165  int p0 = hmap.mesh_.addPoint(resolution * mx_start, resolution * my, h_last);
166  int p1 = hmap.mesh_.addPoint(resolution * mx, resolution * my, h_last);
167  int p2 = hmap.mesh_.addPoint(resolution * mx_start, resolution * my, h2_last);
168  int p3 = hmap.mesh_.addPoint(resolution * mx, resolution * my, h2_last);
169 
170  hmap.mesh_.addTriangle(p2, p1, p0);
171  hmap.mesh_.addTriangle(p1, p2, p3);
172 
173  if (std::abs(h - h2) > 1e-10) {
174  mx_start = mx;
175  } else {
176  mx_start = -1;
177  }
178  }
179  } else if (std::abs(h - h2) > 1e-10) {
180  mx_start = mx;
181  }
182 
183  h_last = h;
184  h2_last = h2;
185  }
186  }
187 
188 
190 
191  return hmap;
192 }
193 
195  unsigned int mx_min, unsigned int my_min,
196  unsigned int mx_max, unsigned int my_max, double resolution) {
197 
198  double max_height = 0;
199  for(unsigned int mx = mx_min; mx < mx_max; ++mx) {
200  for(unsigned int my = my_min; my < my_max; ++my) {
201  max_height = std::max(max_height, map[mx][my]);
202  }
203  }
204 
205  if (max_height == 0) {
206  return 0;
207  }
208 
209  Vector3 min_map((double)mx_min * resolution,
210  (double)my_min * resolution, 0);
211  Vector3 max_map((double)mx_max * resolution,
212  (double)my_max * resolution, max_height);
213 
214  HeightMapNode* n = new HeightMapNode(Box(min_map, max_map));
215 
216  if (mx_max - mx_min == 1 || my_max - my_min == 1) {
217  assert(mx_max - mx_min == 1 && my_max - my_min == 1);
218  n->occupied_ = true;
219  return n;
220  } else {
221  n->occupied_ = false;
222 
223  unsigned int cx = (mx_max + mx_min) / 2;
224  unsigned int cy = (my_max + my_min) / 2;
225 
226  n->children_[0] = createQuadTree(map, mx_min, my_min, cx, cy, resolution);
227  n->children_[1] = createQuadTree(map, cx , my_min, mx_max, cy, resolution);
228  n->children_[2] = createQuadTree(map, mx_min, cy , cx, my_max, resolution);
229  n->children_[3] = createQuadTree(map, cx , cy , mx_max, my_max, resolution);
230 
231  }
232 
233  return n;
234 }
235 
236 }
geo::HeightMap::fromGrid
static HeightMap fromGrid(const std::vector< std::vector< double > > &grid, double resolution)
fromGrid: instantiate a Heightmap from a grid
Definition: HeightMap.cpp:34
std::vector::resize
T resize(T... args)
geo::HeightMap::HeightMap
HeightMap()
Definition: HeightMap.cpp:7
geo::HeightMapNode
Definition: HeightMapNode.h:17
geo
Definition: Box.h:6
geo::HeightMap
A geometric description of a Heightmap using a quad tree.
Definition: HeightMap.h:15
std::vector
geo::HeightMap::createQuadTree
static HeightMapNode * createQuadTree(const std::vector< std::vector< double > > &map, unsigned int mx_min, unsigned int my_min, unsigned int mx_max, unsigned int my_max, double resolution)
createQuadTree: divide a grid over a quad tree
Definition: HeightMap.cpp:194
geo::Box
Definition: Box.h:15
geo::HeightMap::intersect
bool intersect(const Ray &, float t0, float t1, double &distance) const
intersect: currently always throws a logic error
Definition: HeightMap.cpp:27
HeightMap.h
geo::Mesh::addPoint
unsigned int addPoint(double x, double y, double z)
Definition: Mesh.cpp:15
geo::HeightMapNode::intersect
bool intersect(const Ray &r, float t0, float t1, double &distance) const
Definition: HeightMapNode.cpp:39
geo::Ray
Definition: Ray.h:10
geo::HeightMapNode::occupied_
bool occupied_
Definition: HeightMapNode.h:40
geo::Vector3
Definition: matrix.h:12
geo::HeightMap::clone
HeightMap * clone() const
Definition: HeightMap.cpp:23
geo::HeightMapNode::children_
HeightMapNode * children_[4]
Definition: HeightMapNode.h:37
geo::Mesh::filterOverlappingVertices
void filterOverlappingVertices()
Definition: Mesh.cpp:84
geo::Mesh::addTriangle
void addTriangle(unsigned int i1, unsigned int i2, unsigned int i3)
Definition: Mesh.cpp:26
geo::HeightMap::~HeightMap
virtual ~HeightMap()
Definition: HeightMap.cpp:19
std::max
T max(T... args)
geo::Shape::mesh_
Mesh mesh_
Should not be read or written to directly in general. Use setMesh and getMesh to write respectively r...
Definition: Shape.h:112
geo::HeightMap::root_
HeightMapNode * root_
Definition: HeightMap.h:41