removed gridSize from the template arguments

- not needed and code much cleaner
some minor changes
new test-cases
This commit is contained in:
2016-01-25 15:53:12 +01:00
parent 9947dced15
commit 5aedce47f1
16 changed files with 167 additions and 66 deletions

View File

@@ -14,20 +14,21 @@
#include "../misc/Debug.h"
/**
* grid of the given grid-size, storing some value which
* extends GridPoint and GridNode
* grid of a given-size, storing some user-data-value which
* - extends GridPoint and GridNode
*
* Usage:
* for (Node& n : grid) {...}
* for (Node& n2 : grid.neighbors(n)) {...}
*
*/
template <int gridSize_cm, typename T> class Grid {
template <typename T> class Grid {
static constexpr const char* name = "Grid";
#include "GridNeighborIterator.h"
/** UID for nodes */
typedef uint64_t UID;
private:
@@ -38,10 +39,13 @@ private:
/** UID -> index mapping */
std::unordered_map<UID, int> hashes;
/** the user-given grid-size */
const int gridSize_cm;
public:
/** ctor */
Grid() {
/** ctor with the grid's size (in cm) */
Grid(const int gridSize_cm) : gridSize_cm(gridSize_cm) {
static_assert((sizeof(T::_idx) > 0), "T must inherit from GridNode!");
static_assert((sizeof(T::x_cm) > 0), "T must inherit from GridPoint!");
}
@@ -52,12 +56,15 @@ public:
/** no-assign */
void operator = (const Grid& o) = delete;
/** allows for-each iteration over all included nodes */
decltype(nodes.begin()) begin() {return nodes.begin();}
/** allows for-each iteration over all included nodes */
decltype(nodes.end()) end() {return nodes.end();}
/** get the grid's size */
int getGridSize_cm() const {return gridSize_cm;}
/**
* add the given element to the grid.

View File

@@ -8,7 +8,7 @@ class NeighborIter : std::iterator<std::input_iterator_tag, int> {
private:
/** the grid the src-node belongs to */
Grid<gridSize_cm, T>* grid;
Grid<T>* grid;
/** index of the source-node within its grid */
int srcNodeIdx;
@@ -19,8 +19,8 @@ private:
public:
/** ctor */
NeighborIter(const Grid<gridSize_cm, T>& grid, const int srcNodeIdx, const int nIdx) :
grid((Grid<gridSize_cm, T>*)&grid), srcNodeIdx(srcNodeIdx), nIdx(nIdx) {;}
NeighborIter(const Grid<T>& grid, const int srcNodeIdx, const int nIdx) :
grid((Grid<T>*)&grid), srcNodeIdx(srcNodeIdx), nIdx(nIdx) {;}
/** next neighbor */
NeighborIter& operator++() {++nIdx; return *this;}
@@ -44,7 +44,7 @@ class NeighborForEach {
private:
/** the grid the src-node belongs to */
const Grid<gridSize_cm, T>& grid;
const Grid<T>& grid;
/** index of the source-node within its grid */
const int srcNodeIdx;
@@ -52,7 +52,7 @@ private:
public:
/** ctor */
NeighborForEach(const Grid<gridSize_cm, T>& grid, const int srcNodeIdx) :
NeighborForEach(const Grid<T>& grid, const int srcNodeIdx) :
grid(grid), srcNodeIdx(srcNodeIdx) {;}
/** starting point */

View File

@@ -4,7 +4,8 @@
#include "GridNodeBBox.h"
#include "GridPoint.h"
template<int, typename> class Grid;
/** forward decl. */
template<typename> class Grid;
/**
@@ -17,7 +18,8 @@ struct GridNode {
private:
template<int, typename> friend class Grid;
/** grant full access to the grid */
template<typename> friend class Grid;
/** INTERNAL: array-index */
int _idx;

View File

@@ -11,7 +11,7 @@
#include "../../misc/Debug.h"
template <int gridSize_cm, typename T> class GridFactory {
template <typename T> class GridFactory {
/** logging name */
static constexpr const char* name = "GridFac";
@@ -19,19 +19,21 @@ template <int gridSize_cm, typename T> class GridFactory {
private:
/** the grid to build into */
Grid<gridSize_cm, T>& grid;
Grid<T>& grid;
public:
/** ctor with the grid to fill */
GridFactory(Grid<gridSize_cm, T>& grid) : grid(grid) {;}
GridFactory(Grid<T>& grid) : grid(grid) {;}
/** add the given floor at the provided height (in cm) */
void addFloor(const Floor& floor, const float z_cm) {
Log::add(name, "adding floor at height " + std::to_string(z_cm));
const float gridSize_cm = grid.getGridSize_cm();
// build grid-points
for(int x_cm = 0; x_cm < floor.getWidth_cm(); x_cm += gridSize_cm) {
for (int y_cm = 0; y_cm < floor.getDepth_cm(); y_cm += gridSize_cm) {
@@ -55,6 +57,8 @@ public:
Log::add(name, "connecting all adjacent nodes at height " + std::to_string(z_cm));
const int gridSize_cm = grid.getGridSize_cm();
// connect adjacent grid-points
for (int idx = 0; idx < grid.getNumNodes(); ++idx) {
@@ -132,6 +136,8 @@ public:
int idx2 = -1;
const int idx3 = n2.getIdx();
const int gridSize_cm = grid.getGridSize_cm();
// move upards in gridSize steps
for (int z = gridSize_cm; z < zDiff; z+= gridSize_cm) {
@@ -161,11 +167,13 @@ public:
}
/** add the inverted version of the given z-layer */
void addInverted(const Grid<gridSize_cm, T>& gIn, const float z_cm) {
void addInverted(const Grid<T>& gIn, const float z_cm) {
// get the original grid's bbox
BBox3 bb = gIn.getBBox();
const int gridSize_cm = grid.getGridSize_cm();
// build new grid-points
for(int x_cm = bb.getMin().x; x_cm <= bb.getMax().x; x_cm += gridSize_cm) {
for (int y_cm = bb.getMin().y; y_cm < bb.getMax().y; y_cm += gridSize_cm) {

View File

@@ -31,25 +31,26 @@ private:
public:
/** attach importance-factors to the grid */
template <int gridSize_cm, typename T> void addImportance(Grid<gridSize_cm, T>& g, const float z_cm) {
template <typename T> void addImportance(Grid<T>& g, const float z_cm) {
Log::add(name, "adding importance information to all nodes at height " + std::to_string(z_cm));
// get an inverted version of the grid
Grid<gridSize_cm, T> inv;
GridFactory<gridSize_cm, T> fac(inv);
Grid<T> inv(g.getGridSize_cm());
GridFactory<T> fac(inv);
fac.addInverted(g, z_cm);
// construct KNN search
KNN<Grid<gridSize_cm, T>, 3> knn(inv);
KNN<Grid<T>, 3> knn(inv);
// the number of neighbors to use
static constexpr int numNeighbors = 8;
for (int idx = 0; idx < g.getNumNodes(); ++idx) {
// create list of all doors
std::vector<T> doors;
// process each point
T& n1 = (T&) g[idx];
// process each node
for (T& n1 : g) {
// get the 10 nearest neighbors and their distance
size_t indices[numNeighbors];
@@ -64,14 +65,51 @@ public:
}
addImportance(n1, Units::cmToM(std::sqrt(squaredDist[0])) );
addDoor(n1, neighbors);
//addDoor(n1, neighbors);
// is the current node a door?
if (isDoor(n1, neighbors)) {doors.push_back(n1);}
// favor stairs just like doors
if (isStaircase(g, n1)) {doors.push_back(n1);}
}
KNNArray<std::vector<T>> knnArrDoors(doors);
KNN<KNNArray<std::vector<T>>, 3> knnDoors(knnArrDoors);
// process each node again
for (T& n1 : g) {
static K::NormalDistribution favorDoors(0.0, 0.6);
// get the distance to the nearest door
const float dist_m = Units::cmToM(knnDoors.getNearestDistance( {n1.x_cm, n1.y_cm, n1.z_cm} ));
// importance for this node (based on the distance from the next door)
const float imp = 1.0 + favorDoors.getProbability(dist_m) * 0.35;
// adjust
n1.imp *= imp;
}
}
/** is the given node connected to a staircase? */
template <typename T> bool isStaircase(Grid<T>& g, T& node) {
// if this node has a neighbor with a different z, this is a stair
for (T& neighbor : g.neighbors(node)) {
if (neighbor.z_cm != node.z_cm) {return true;}
}
return false;
}
/** attach importance-factors to the grid */
template <int gridSize_cm, typename T> void addDistanceToTarget(Grid<gridSize_cm, T>& g, Dijkstra<T>& d) {
template <typename T> void addDistanceToTarget(Grid<T>& g, Dijkstra<T>& d) {
//Log::add(name, "adding importance information to all nodes at height " + std::to_string(z_cm));
@@ -87,7 +125,7 @@ public:
}
template <int gridSize_cm, typename T> void addImportance(Grid<gridSize_cm, T>& g, DijkstraNode<T>* start, DijkstraNode<T>* end) {
template <typename T> void addImportance(Grid<T>& g, DijkstraNode<T>* start, DijkstraNode<T>* end) {
// routing path
DijkstraPath<T> path(end, start);
@@ -112,8 +150,8 @@ public:
}
/** add importance to nSrc if it is part of a door */
template <typename T> void addDoor( T& nSrc, std::vector<T*> neighbors ) {
/** is the given node (and its inverted neighbors) a door? */
template <typename T> bool isDoor( T& nSrc, std::vector<T*> neighbors ) {
MiniMat2 m;
Point3 center = nSrc;
@@ -126,7 +164,7 @@ public:
centroid /= neighbors.size();
// if nSrc is too far from the centroid, this does not make sense
if ((centroid-center).length() > 60) {return;}
if ((centroid-center).length() > 20) {return false;}
// build covariance of the nearest-neighbors
int used = 0;
@@ -138,7 +176,7 @@ public:
}
// we need at least two points for the covariance
if (used < 2) {return;}
if (used < 2) {return false;}
// check eigenvalues
MiniMat2::EV ev = m.getEigenvalues();
@@ -147,7 +185,7 @@ public:
if (ev.e1 < ev.e2) {std::swap(ev.e1, ev.e2);}
// door?
if ((ev.e2/ev.e1) < 0.15) { nSrc.imp *= 1.3; }
return ((ev.e2/ev.e1) < 0.15) ;
}

View File

@@ -41,7 +41,7 @@ private:
public:
/** ctor with the target you want to reach */
template <int gridSize_cm, typename Access> GridWalkLightAtTheEndOfTheTunnel(Grid<gridSize_cm, T>& grid, const Access& acc, const T& target) {
template <typename Access> GridWalkLightAtTheEndOfTheTunnel(Grid<T>& grid, const Access& acc, const T& target) {
// build all shortest path to reach th target
dijkstra.build(target, target, acc);
@@ -60,7 +60,7 @@ public:
}
template <int gridSize_cm> GridWalkState<T> getDestination(Grid<gridSize_cm, T>& grid, GridWalkState<T> start, float distance_m) {
GridWalkState<T> getDestination(Grid<T>& grid, GridWalkState<T> start, float distance_m) {
int retries = 2;
GridWalkState<T> res;
@@ -84,7 +84,7 @@ public:
private:
template <int gridSize_cm> GridWalkState<T> walk(Grid<gridSize_cm, T>& grid, GridWalkState<T> cur, float distRest_m) {
GridWalkState<T> walk(Grid<T>& grid, GridWalkState<T> cur, float distRest_m) {
drawer.reset();;

View File

@@ -45,7 +45,7 @@ private:
public:
template <int gridSize_cm> State getDestination(Grid<gridSize_cm, T>& grid, State start, float distance_m) {
template <int gridSize_cm> State getDestination(Grid<T>& grid, State start, float distance_m) {
int retries = 2;
State res;
@@ -73,7 +73,7 @@ private:
return Heading(from.x_cm, from.y_cm, to.x_cm, to.y_cm);
}
template <int gridSize_cm> State walk(Grid<gridSize_cm, T>& grid, State cur, float distRest_m) {
State walk(Grid<T>& grid, State cur, float distRest_m) {
drawer.reset();;