#ifndef INTERPOLATOR_H #define INTERPOLATOR_H #include #include namespace K { /** * this class allows adding values with some sort of key. * hereafter it is possible to interpolate between two values * using a provided key. */ template class Interpolator { /** combine key and value within one struct */ struct KeyedEntry { Key key; Value val; KeyedEntry(const Key key, const Value& val) : key(key), val(val) {;} }; public: /** all entries within the interpolator */ std::vector values; public: /** add a new timed entry */ void add(const Key key, const Value& val) { values.push_back(KeyedEntry(key, val)); } /** get the interpolated value for the given key */ Value get(const Key key) const { auto comp = [] (const Key& key, const KeyedEntry& e) {return key < e.key;}; auto it = std::upper_bound(values.begin(), values.end(), key, comp); // first element > key const KeyedEntry eH = *it; // greater than key const KeyedEntry eL = *(--it); // smaller than key const Key diff = eH.key - eL.key; // distance between upper and lower bound const float vL = float(eH.key - key) / float(diff); // influence factor for the smaller one const float vH = float(key - eL.key) / float(diff); // influence factor for the larger one return (eH.val * vH) + (eL.val * vL); // interpolate } /** ensure the first key starts at 0 */ void makeRelative() { const Key firstKey = values[0].key; for (KeyedEntry& e : values) {e.key -= firstKey;} } }; } #endif // INTERPOLATOR_H