This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/grid/walk/v3/ReachableSampler.h
2018-10-25 11:50:12 +02:00

92 lines
2.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © Copyright 2014 Urheberrechtshinweis
* Alle Rechte vorbehalten / All Rights Reserved
*
* Programmcode ist urheberrechtlich geschuetzt.
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
* Keine Verwendung ohne explizite Genehmigung.
* (vgl. § 106 ff UrhG / § 97 UrhG)
*/
#ifndef INDOOR_GW3_REACHABLESAMPLER_H
#define INDOOR_GW3_REACHABLESAMPLER_H
#include "../../../math/random/RandomGenerator.h"
#include "Reachable.h"
#include "Helper.h"
namespace GW3 {
template <typename Node> class ReachableSamplerByDepth {
public:
using Entry = typename ReachableByDepthWithDistanceSorted<Node>::Entry;
struct SampleResult {
Point3 pos;
float walkDistToStart_m;
SampleResult(const Point3 pos, const float dist_m) : pos(pos), walkDistToStart_m(dist_m) {;}
};
private:
const Grid<Node>& grid;
const float gridSize_m;
const std::vector<Entry>& reachableNodes;
mutable Random::RandomGenerator gen;
mutable std::uniform_real_distribution<float> dOffset;
public:
/** ctor */
ReachableSamplerByDepth(const Grid<Node>& grid, const std::vector<Entry>& reachableNodes) :
grid(grid), reachableNodes(reachableNodes), gridSize_m(grid.getGridSize_cm() / 100.0f), dOffset(-gridSize_m*0.48f, +gridSize_m*0.48f) {
;
}
SampleResult sample() {
std::uniform_int_distribution<int> dIdx(0, reachableNodes.size() - 1);
const int idx = dIdx(gen);
const Entry* e = &reachableNodes[idx];
const Entry* ePrev1 = (e->prevIdx == -1) ? (nullptr) : (&reachableNodes[e->prevIdx]);
const Node* nDst = e->node;
// center of the destination node
const Point3 nodeCenter = Helper<Node>::gpToP3(*nDst);
// random position within destination-node
const float ox = dOffset(gen);
const float oy = dOffset(gen);
// destination = nodeCenter + offset (within the node's bbox, (x,y) only! keep z as-is)
const Point3 end(nodeCenter.x + ox, nodeCenter.y + oy, nodeCenter.z);
// calculate end's walking-distance towards the start
float distToStart_m;
if (ePrev1) {
distToStart_m = ePrev1->walkDistToStart_m + (Helper<Node>::gpToP3(*(ePrev1->node)).getDistance(end));
} else {
distToStart_m = nodeCenter.getDistance(end);
}
// done
return SampleResult(end, distToStart_m);
}
};
}
#endif // REACHABLESAMPLER_H