geometry changes/fixes/new features
new grid walkers + fixes new test-cases worked on step/and turn detection android offline-data-reader worked on vap-grouping
This commit is contained in:
@@ -18,18 +18,7 @@
|
||||
#include <functional>
|
||||
|
||||
|
||||
/** listen for events during the build process */
|
||||
class GridFactoryListener {
|
||||
|
||||
public:
|
||||
|
||||
virtual void onGridBuildUpdateMajor(const std::string& what) = 0;
|
||||
virtual void onGridBuildUpdateMajor(const int cnt, const int cur) = 0;
|
||||
|
||||
virtual void onGridBuildUpdateMinor(const std::string& what) = 0;
|
||||
virtual void onGridBuildUpdateMinor(const int cnt, const int cur) = 0;
|
||||
|
||||
};
|
||||
#include "GridFactoryListener.h"
|
||||
|
||||
|
||||
template <typename T> class GridFactory {
|
||||
@@ -156,7 +145,7 @@ public:
|
||||
GridNodeBBox bbox(GridPoint(x_cm, y_cm, z_cm), helper.gridSize());
|
||||
|
||||
// slightly grow the bbox to ensure even obstacles that are directly aligned to the bbox are hit
|
||||
bbox.grow(0.012345);
|
||||
bbox.grow(0.42345);
|
||||
if (intersects(bbox, floor)) {continue;}
|
||||
|
||||
// add to the grid
|
||||
@@ -170,7 +159,7 @@ public:
|
||||
}
|
||||
|
||||
// connect the g
|
||||
connectAdjacent(z_cm);
|
||||
connectAdjacent(floor, z_cm);
|
||||
|
||||
}
|
||||
|
||||
@@ -186,6 +175,9 @@ public:
|
||||
if (listener) {listener->onGridBuildUpdateMinor(total, ++cur);}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
stairs.finalize();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -273,7 +265,7 @@ public:
|
||||
}
|
||||
|
||||
/** connect all neighboring nodes located on the given height-plane */
|
||||
void connectAdjacent(const float z_cm) {
|
||||
void connectAdjacent(const Floorplan::Floor* floor, const float z_cm) {
|
||||
|
||||
Log::add(name, "connecting all adjacent nodes at height " + std::to_string(z_cm), false);
|
||||
Log::tick();
|
||||
@@ -285,7 +277,7 @@ public:
|
||||
if (n1.z_cm != z_cm) {continue;}
|
||||
|
||||
// connect the node with its neighbors
|
||||
connectAdjacent(n1);
|
||||
connectAdjacent(floor, n1);
|
||||
|
||||
}
|
||||
|
||||
@@ -293,8 +285,13 @@ public:
|
||||
|
||||
}
|
||||
|
||||
/** connect the given node with its neighbors */
|
||||
void connectAdjacent(T& n1) {
|
||||
/**
|
||||
* connect the given node with its neighbors.
|
||||
* even though a node has a neighbor, it might still be blocked by an obstacle:
|
||||
* e.g. a 45° wall directly between nodes. a neighbor exists, but is unreachable due to the wall.
|
||||
* we thus perform an additional intersection check with all obstacles within the floor the node n1 belongs to
|
||||
*/
|
||||
void connectAdjacent(const Floorplan::Floor* floor, T& n1) {
|
||||
|
||||
const int gridSize_cm = grid.getGridSize_cm();
|
||||
|
||||
@@ -313,6 +310,7 @@ public:
|
||||
// does the grid contain the potential neighbor?
|
||||
const T* n2 = grid.getNodePtrFor(p);
|
||||
if (n2 != nullptr) {
|
||||
if (isBlocked(floor, n1, *n2)) {continue;} // is there a (e.g. small) obstacle between the two?
|
||||
grid.connectUniDir(n1, *n2); // UNI-dir connection as EACH node is processed!
|
||||
}
|
||||
|
||||
@@ -479,7 +477,46 @@ private:
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* normally, the algorithm will not try to connect two nodes that are neighbors but have an obstacle between them.
|
||||
* however, especially for 45° obstacles it might happen that a neighbor exists but is blocked by an obstacle.
|
||||
* we thus need this additional check to ensure everything is fine... even though it needs performance...
|
||||
*/
|
||||
static inline bool isBlocked(const Floorplan::Floor* floor, const GridPoint& n1, const GridPoint& n2) {
|
||||
|
||||
// (obstacles use meter, while the nodes are in centimeter!
|
||||
const Point2 p1_m = n1.inMeter().xy();
|
||||
const Point2 p2_m = n2.inMeter().xy();
|
||||
const Line2 lineNodes(p1_m, p2_m);
|
||||
|
||||
// process each obstacle
|
||||
for (Floorplan::FloorObstacle* fo : floor->obstacles) {
|
||||
|
||||
// depends on the type of obstacle
|
||||
if (dynamic_cast<Floorplan::FloorObstacleLine*>(fo)) {
|
||||
const Floorplan::FloorObstacleLine* line = (Floorplan::FloorObstacleLine*) fo;
|
||||
const Line2 lineObstacle(line->from, line->to);
|
||||
if (lineObstacle.getSegmentIntersection(lineNodes)) {return true;}
|
||||
|
||||
} else if (dynamic_cast<Floorplan::FloorObstacleCircle*>(fo)) {
|
||||
throw Exception("should not happen");
|
||||
|
||||
} else if (dynamic_cast<Floorplan::FloorObstacleDoor*>(fo)) {
|
||||
// DOORS ARE NOT AN OBSTACLE
|
||||
|
||||
} else {
|
||||
throw Exception("TODO: not yet implemented obstacle type");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/** does the bbox intersect with any of the floor's walls? */
|
||||
|
||||
Reference in New Issue
Block a user