worked on 3d models within map

adjusted grid factory
adjusted nav mesh factory
minoor changes/fixes
new helper classes
refactoring
This commit is contained in:
2018-04-03 14:55:59 +02:00
parent f3b6155157
commit 1c2081d406
25 changed files with 620 additions and 93 deletions

View File

@@ -31,5 +31,16 @@ public:
};
namespace std {
template<class T> const T& min(const T& a, const T& b, const T& c) {
return min(a, min(b,c));
}
template<class T> const T& min(const T& a, const T& b, const T& c, const T& d) {
return min(a, min(b, min(c,d)));
}
}
#endif // K_MATH_MATH_H

View File

@@ -0,0 +1,59 @@
#ifndef CHISQUARED_H
#define CHISQUARED_H
#include <cmath>
namespace Distribution {
/**
* https://en.wikipedia.org/wiki/Chi-squared_distribution
* @brief The ChiSquared class
*/
template <typename Scalar> class ChiSquared {
private:
// degrees of freedom
int k;
public:
/** ctor */
ChiSquared(const int k) : k(k) {
;
}
Scalar get(const Scalar val) const {
const Scalar k2 = k/((Scalar)2);
const Scalar k2_1 = k2 - 1;
const Scalar gamma = std::tgamma(k2);
return 1.0 / (std::pow(2, k2)*gamma) * std::pow(val, k2_1) * std::exp(-val/2);
}
Scalar getInvCDF(const Scalar val) const {
// brute-force get the inverse CDF...
const Scalar ss = 0.002;
Scalar sum = 0;
for (float t = 0; t < 20; t += ss) {
sum += get(t) * ss;
if (sum >= val) {
return t;
}
}
throw "failed";
}
};
}
#endif // CHISQUARED_H

View File

@@ -17,7 +17,7 @@ namespace Distribution {
const T sigma;
const T _a;
Random::RandomGenerator gen;
Random::RandomGenerator gen;
std::normal_distribution<T> dist;
public:
@@ -32,6 +32,11 @@ namespace Distribution {
mu(mu), sigma(sigma), _a(1.0 / (sigma * std::sqrt(2.0 * M_PI))), gen(seed), dist(mu,sigma) {
}
/** mu = 0, sigma = 1 */
static Normal unit() {
return Normal(0,1);
}
/** do not allow copy. this will not work as expected for std::normal_distribution when using draw() ?! */
//Normal(const Normal& o) = delete;
@@ -51,15 +56,15 @@ namespace Distribution {
gen.seed(seed);
}
/** get the mean value */
const T getMu() {
return this->mu;
}
/** get the mean value */
const T getMu() {
return this->mu;
}
/** get the standard deviation */
const T getSigma() {
return this->sigma;
}
/** get the standard deviation */
const T getSigma() {
return this->sigma;
}
/** get the probability for the given value */
static T getProbability(const T mu, const T sigma, const T val) {

View File

@@ -8,6 +8,8 @@
#include "../../Assertions.h"
#include "../random/RandomGenerator.h"
#include "../../geo/Point2.h"
#include "ChiSquared.h"
namespace Distribution {
@@ -96,6 +98,43 @@ namespace Distribution {
return NormalDistributionN(mean, cov);
}
std::vector<Point2> getContour2(const double percentWithin) {
const int degreesOfFreedom = 2; // 2D distribution
const ChiSquared<double> chi(degreesOfFreedom);
// https://people.richland.edu/james/lecture/m170/tbl-chi.html
Assert::isNear(0.103, chi.getInvCDF(0.05), 0.01, "error within chi-squared distribution");
Assert::isNear(0.211, chi.getInvCDF(0.10), 0.01, "error within chi-squared distribution");
Assert::isNear(4.605, chi.getInvCDF(0.90), 0.01, "error within chi-squared distribution");
Assert::isNear(5.991, chi.getInvCDF(0.95), 0.03, "error within chi-squared distribution");
// size of the ellipse using confidence intervals
const float mul = chi.getInvCDF(percentWithin);
std::vector<Point2> res;
std::cout << sigma << std::endl;
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(this->sigma);
Eigen::Vector2d evec1 = solver.eigenvectors().col(0);
Eigen::Vector2d evec2 = solver.eigenvectors().col(1);
double eval1 = solver.eigenvalues()(0);
double eval2 = solver.eigenvalues()(1);
for (int deg = 0; deg <= 360; deg += 5) {
const float rad = deg / 180.0f * M_PI;
Eigen::Vector2d pos =
std::cos(rad) * std::sqrt(mul * eval1) * evec1 +
std::sin(rad) * std::sqrt(mul * eval2) * evec2;
res.push_back(Point2(pos(0), pos(1)));
}
return res;
}
};
}

View File

@@ -14,7 +14,7 @@ namespace Distribution {
private:
Random::RandomGenerator gen;
Random::RandomGenerator gen;
/** depending on T, Dist is either a uniform_real or uniform_int distribution */
typedef typename std::conditional< std::is_floating_point<T>::value, std::uniform_real_distribution<T>, std::uniform_int_distribution<T> >::type Dist;
@@ -33,6 +33,11 @@ namespace Distribution {
}
/** -1 to +1 */
static Uniform unit() {
return Uniform(-1, +1);
}
/** get a uniformaly distributed random number */
T draw() {
return dist(gen);

View File

@@ -12,15 +12,15 @@
namespace Random {
class RandomGenerator : public std::minstd_rand {
class RandomGenerator : public std::minstd_rand {
public:
/** ctor with default seed */
RandomGenerator() : std::minstd_rand(RANDOM_SEED) {;}
RandomGenerator() : std::minstd_rand(RANDOM_SEED) {;}
/** ctor with custom seed */
RandomGenerator(result_type) : std::minstd_rand(RANDOM_SEED) {;}
RandomGenerator(result_type) : std::minstd_rand(RANDOM_SEED) {;}
};

53
math/stats/Histogram2.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef HISTOGRAM2_H
#define HISTOGRAM2_H
#include <vector>
#include "../../geo/BBox2.h"
namespace Stats {
/** 2D histogram */
template <typename Scalar> class Histogram2 {
std::vector<Scalar> vec;
BBox2 bbox;
int binsX;
int binsY;
public:
/** ctor */
Histogram2(BBox2 bbox, int binsX, int binsY) : bbox(bbox), binsX(binsX), binsY(binsY) {
vec.resize(binsX*binsY);
}
Scalar get(Scalar x, Scalar y) const {
const int idx = binIdx(x,y);
return vec[idx];
}
void add(Scalar x, Scalar y, Scalar val) {
const int idx = binIdx(x,y);
vec[idx] += val;
}
int binIdx(const Scalar x, const Scalar y) {
const int ix = binIdxX(x);
const int iy = binIdxY(y);
return ix + iy*binsX;
}
int binIdxX(const Scalar val) const {
return (val - bbox.getMin().x) / (bbox.getSize().x) * binsX;
}
int binIdxY(const Scalar val) const {
return (val - bbox.getMin().y) / (bbox.getSize().y) * binsY;
}
};
}
#endif // HISTOGRAM2_H