added new data-structures

added new test-cases
added flexible dijkstra calculation
added debugging log
modified: plotting, grid-generation, grid-importance,
refactoring
This commit is contained in:
2016-01-22 18:47:06 +01:00
parent 12084fe147
commit cdf97322f8
21 changed files with 720 additions and 141 deletions

View File

@@ -2,15 +2,16 @@
#define GRID_H
#include <vector>
#include <iostream>
#include <unordered_map>
#include "../Exception.h"
#include "GridPoint.h"
#include "GridNode.h"
#include <iostream>
#include <KLib/Assertions.h>
#include "../geo/BBox3.h"
#include "../misc/Debug.h"
/**
* grid of the given grid-size, storing some value which
@@ -18,7 +19,11 @@
*/
template <int gridSize_cm, typename T> class Grid {
typedef uint64_t UID;
static constexpr const char* name = "Grid";
#include "GridNeighborIterator.h"
typedef uint64_t UID;
private:
@@ -72,10 +77,7 @@ public:
void connectUniDir(T& n1, const T& n2) {
n1._neighbors[n1._numNeighbors] = n2._idx;
++n1._numNeighbors;
if (n1._numNeighbors > 12) {
int i = 0;
}
_assertBetween(n1._numNeighbors, 0, 12, "number of neighbors out of bounds!");
_assertBetween(n1._numNeighbors, 0, 10, "number of neighbors out of bounds!");
}
/**
@@ -154,14 +156,21 @@ public:
*
*/
UID getUID(const GridPoint& p) const {
const uint64_t x = std::round(p.x_cm / gridSize_cm);
const uint64_t y = std::round(p.y_cm / gridSize_cm);
const uint64_t z = std::round(p.z_cm / gridSize_cm);
const uint64_t x = std::round(p.x_cm / (float)gridSize_cm);
const uint64_t y = std::round(p.y_cm / (float)gridSize_cm);
const uint64_t z = std::round(p.z_cm / (float)gridSize_cm);
return (z << 40) | (y << 20) | (x << 0);
}
/** array access */
T& operator [] (const int idx) {
_assertBetween(idx, 0, getNumNodes()-1, "index out of bounds");
return nodes[idx];
}
/** const array access */
const T& operator [] (const int idx) const {
_assertBetween(idx, 0, getNumNodes()-1, "index out of bounds");
return nodes[idx];
}
@@ -223,48 +232,57 @@ public:
*/
void cleanup() {
for (size_t i = 0; i < nodes.size(); ++i) {
Log::add(name, "running grid cleanup");
// check every single node
for (int i = (int)nodes.size() - 1; i >= 0; --i) {
// is this node marked as "deleted"? (idx == -1)
if (nodes[i]._idx == -1) {
nodes.erase(nodes.begin()+i);
moveDown(i);
--i;
// remove this node
deleteNode(i);
++i;
}
}
// rebuild hashes
Log::add(name, "rebuilding UID hashes");
hashes.clear();
for (size_t idx = 0; idx < nodes.size(); ++idx) {
hashes[getUID(nodes[idx])] = idx;
}
}
void moveDown(const int idx) {
private:
/** hard-delete the given node */
void deleteNode(const int idx) {
// COMPLEX AND SLOW AS HELL.. BUT UGLY TO REWIRTE TO BE CORRECT
// remove him from the node list (reclaim its memory and its index)
nodes.erase(nodes.begin()+idx);
// decrement the index for all of the following nodes and adjust neighbor references
for (size_t i = 0; i < nodes.size(); ++i) {
if (nodes[i]._idx >= idx) {--nodes[i]._idx;}
// decrement the higher indices (reclaim the free one)
if (nodes[i]._idx >= idx) { --nodes[i]._idx;}
// adjust the neighbor references (decrement by one)
for (int n = 0; n < nodes[i]._numNeighbors; ++n) {
if (nodes[i]._neighbors[n] >= idx) {--nodes[i]._neighbors[n];}
}
}
}
class NeighborIter : std::iterator<std::input_iterator_tag, int> {
private:
Grid<gridSize_cm, T>& grid;
int nodeIdx;
int nIdx;
public:
NeighborIter(Grid<gridSize_cm, T>& grid, const int nodeIdx, const int nIdx) : grid(grid), nodeIdx(nodeIdx), nIdx(nIdx) {;}
NeighborIter& operator++() {++nIdx; return *this;}
NeighborIter operator++(int) {NeighborIter tmp(*this); operator++(); return tmp;}
bool operator==(const NeighborIter& rhs) {return nodeIdx == rhs.nodeIdx && nIdx == rhs.nIdx;}
bool operator!=(const NeighborIter& rhs) {return nodeIdx != rhs.nodeIdx || nIdx != rhs.nIdx;}
T& operator*() {return (T&) grid.nodes[nodeIdx]._neighbors[nIdx];}
};
public:
class NeighborForEach {
private:
Grid<gridSize_cm, T>& grid;
int nodeIdx;
public:
NeighborForEach(Grid<gridSize_cm, T>& grid, const int nodeIdx) : grid(grid), nodeIdx(nodeIdx) {;}
NeighborIter begin() {return NeighborIter(grid, nodeIdx, 0);}
NeighborIter end() {return NeighborIter(grid, nodeIdx, grid[nodeIdx]._numNeighbors);}
};
NeighborForEach neighbors(const int idx) {
return neighbors(nodes[idx]);
@@ -287,7 +305,7 @@ public:
return nodes.size();
}
template <class BBOX> bool kdtree_get_bbox(BBOX& bb) const { return false; }
template <class BBOX> bool kdtree_get_bbox(BBOX& bb) const { (void) bb; return false; }
inline float kdtree_get_pt(const size_t idx, const int dim) const {
const T& p = nodes[idx];