glviewvol
diff src/curve.cc @ 4:04330eb80b36
lots of stuff
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 29 Dec 2014 05:41:36 +0200 |
parents | |
children | 71b479ffb9f7 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/curve.cc Mon Dec 29 05:41:36 2014 +0200 1.3 @@ -0,0 +1,106 @@ 1.4 +#include <algorithm> 1.5 +#include "curve.h" 1.6 + 1.7 +#define CLAMP(x, low, high) std::min<float>(std::max<float>(x, low), high) 1.8 +#define INDEX(x) ((x) * 65535.0) 1.9 + 1.10 +void Curve::set_point(float t, float val) 1.11 +{ 1.12 + uint16_t x = INDEX(CLAMP(t, 0.0, 1.0)); 1.13 + set_point_int(x, val); 1.14 +} 1.15 + 1.16 +static bool cpcmp(const CurvePoint &a, const CurvePoint &b) 1.17 +{ 1.18 + return a.t_int < b.t_int; 1.19 +} 1.20 + 1.21 +void Curve::set_point_int(uint16_t ti, float val) 1.22 +{ 1.23 + CurvePoint *p = get_point_at(ti); 1.24 + if(p) { 1.25 + p->value = val; 1.26 + } else { 1.27 + CurvePoint p; 1.28 + p.t_int = ti; 1.29 + p.value = val; 1.30 + cp.push_back(p); 1.31 + std::sort(cp.begin(), cp.end(), cpcmp); 1.32 + } 1.33 +} 1.34 + 1.35 +bool Curve::delete_point(uint16_t ti) 1.36 +{ 1.37 + int sz = (int)cp.size(); 1.38 + for(int i=0; i<sz; i++) { 1.39 + if(cp[i].t_int == ti) { 1.40 + cp.erase(cp.begin() + i); 1.41 + return true; 1.42 + } 1.43 + } 1.44 + return false; 1.45 +} 1.46 + 1.47 +CurvePoint *Curve::get_point(int idx) 1.48 +{ 1.49 + if(idx < 0 || idx >= cp.size()) { 1.50 + return 0; 1.51 + } 1.52 + return &cp[idx]; 1.53 +} 1.54 + 1.55 +const CurvePoint *Curve::get_point(int idx) const 1.56 +{ 1.57 + if(idx < 0 || idx >= cp.size()) { 1.58 + return 0; 1.59 + } 1.60 + return &cp[idx]; 1.61 +} 1.62 + 1.63 +int Curve::get_num_points() const 1.64 +{ 1.65 + return (int)cp.size(); 1.66 +} 1.67 + 1.68 +CurvePoint *Curve::get_point_at(uint16_t ti) 1.69 +{ 1.70 + int sz = (int)cp.size(); 1.71 + for(int i=0; i<sz; i++) { 1.72 + if(cp[i].t_int == ti) { 1.73 + return &cp[i]; 1.74 + } 1.75 + } 1.76 + return 0; 1.77 +} 1.78 + 1.79 +const CurvePoint *Curve::get_point_at(uint16_t ti) const 1.80 +{ 1.81 + int sz = (int)cp.size(); 1.82 + for(int i=0; i<sz; i++) { 1.83 + if(cp[i].t_int == ti) { 1.84 + return &cp[i]; 1.85 + } 1.86 + } 1.87 + return 0; 1.88 +} 1.89 + 1.90 +float Curve::value(float t) const 1.91 +{ 1.92 + uint16_t x = INDEX(CLAMP(t, 0.0, 1.0)); 1.93 + return value_int(x); 1.94 +} 1.95 + 1.96 +float Curve::value_int(uint16_t ti) const 1.97 +{ 1.98 + CurvePoint p = { ti, 0 }; 1.99 + std::vector<CurvePoint>::const_iterator it; 1.100 + it = std::lower_bound(cp.begin(), cp.end(), p, cpcmp); 1.101 + if(ti >= it->t_int || it == cp.begin()) { 1.102 + return it->value; 1.103 + } 1.104 + 1.105 + std::vector<CurvePoint>::const_iterator prev = it - 1; 1.106 + 1.107 + float t = (float)(ti - prev->t_int) / (float)(it->t_int - prev->t_int); 1.108 + return prev->value + (it->value - prev->value) * t; 1.109 +}