Skip to content

Instantly share code, notes, and snippets.

@r-lyeh-archived
Last active March 30, 2016 20:54
Show Gist options
  • Save r-lyeh-archived/f0548e6a71c4cee4b48a to your computer and use it in GitHub Desktop.
Save r-lyeh-archived/f0548e6a71c4cee4b48a to your computer and use it in GitHub Desktop.
map<K,V> interpolator
// map<K,V> interpolator (requires keys and values with arithmetical operators)
// - rlyeh, public domain
#pragma once
#include <algorithm>
enum {
// supported easings
at_linear = 0,
at_quadinout = 1,
// default configuration (feel free to customize)
at_interpolator = at_quadinout,
at_clamp_invalid_keys = true, // safe version (input keys outside boundaries will be clamped to valid extreme values)
};
template<typename MAP>
static inline typename MAP::mapped_type at( const MAP &map, const typename MAP::key_type &key ) {
auto p1 = map.lower_bound( key );
if( at_clamp_invalid_keys ) {
if( p1 == map.begin() ) {
return map.begin()->second;
}
if( p1 == map.end() ) {
return map.rbegin()->second;
}
}
if( p1->first != key ) {
const auto &p0 = p1--;
double dt01 = ( key - p0->first ) / double( p1->first - p0->first );
if( at_interpolator == at_quadinout ) {
dt01 = ( dt01 < 0.5 ? (2 * dt01 * dt01) : ((-2 * dt01 * dt01) + (4 * dt01) - 1) );
}
return p0->second * (1-dt01) + p1->second * dt01;
}
return p1->second;
}
#ifdef AT_TEST_MAIN
#include <map>
#include <iostream>
int main() {
std::map< int, double > map {
{ 10, 100.0 },
{ 20, 200.0 },
{ 30, 300.0 },
{ 40, 400.0 },
{ 50, 500.0 },
};
std::cout << "[ 0]=" << at(map, 0) << std::endl;
std::cout << "[ 10]=" << at(map, 10) << std::endl;
std::cout << "[ 15]=" << at(map, 15) << std::endl;
std::cout << "[ 20]=" << at(map, 20) << std::endl;
std::cout << "[ 25]=" << at(map, 25) << std::endl;
std::cout << "[ 30]=" << at(map, 30) << std::endl;
std::cout << "[ 35]=" << at(map, 35) << std::endl;
std::cout << "[ 40]=" << at(map, 40) << std::endl;
std::cout << "[ 45]=" << at(map, 45) << std::endl;
std::cout << "[ 50]=" << at(map, 50) << std::endl;
std::cout << "[ 55]=" << at(map, 55) << std::endl;
}
/* possible output:
[ 0]=100
[ 10]=100
[ 15]=150
[ 20]=200
[ 25]=250
[ 30]=300
[ 35]=350
[ 40]=400
[ 45]=450
[ 50]=500
[ 55]=500
*/
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment