#ifndef WALKMODULESPREAD_H #define WALKMODULESPREAD_H #include "WalkModule.h" #include "WalkStateHeading.h" #include "../../../../Assertions.h" /** state-parameter needed for WalkModuleSpread */ struct WalkStateSpread { /** nested struct to prevent name-clashes */ struct { /** keep something like a moving-average-position we want to strictly depart from */ GridPoint departFrom; } spread; }; /** * simply try to move away from the starting node as much as possible */ template class WalkModuleSpread : public WalkModule { private: /** * how fast to adjust the average-position to depart from * values between 3% and 10% seem fine */ const float kappa = 0.10; public: /** ctor */ WalkModuleSpread() { /** ensure the templated WalkState inherits from WalkStateSpread */ StaticAssert::AinheritsB(); } virtual void updateBefore(WalkState& state, const Node& startNode) override { (void) state; (void) startNode; } virtual void updateAfter(WalkState& state, const Node& startNode, const Node& endNode) override { (void) state; (void) startNode; (void) endNode; } virtual void step(WalkState& state, const Node& curNode, const Node& nextNode) override { (void) curNode; state.spread.departFrom = state.spread.departFrom * (1.0f-kappa) + nextNode * (kappa); } double getProbability(const WalkState& state, const Node& startNode, const Node& curNode, const Node& potentialNode) const override { (void) startNode; // current distance from the depart-from position const float dOld = state.spread.departFrom.getDistanceInCM(curNode); // potential distance from the depart-from position const float dNew = state.spread.departFrom.getDistanceInCM(potentialNode); // now, favor edges that depart even further from the depart-from position! if (dNew > dOld) {return 0.90;} // departing if (dNew == dOld) {return 0.09;} // distance does not change {return 0.01;} // NOT departing.. unlikely } }; #endif // WALKMODULESPREAD_H