glviewvol

annotate src/curve.cc @ 7:71b479ffb9f7

curve manipulation works
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 30 Dec 2014 17:28:38 +0200
parents 04330eb80b36
children 773f89037a35
rev   line source
nuclear@4 1 #include <algorithm>
nuclear@4 2 #include "curve.h"
nuclear@4 3
nuclear@4 4 #define CLAMP(x, low, high) std::min<float>(std::max<float>(x, low), high)
nuclear@4 5 #define INDEX(x) ((x) * 65535.0)
nuclear@4 6
nuclear@4 7 void Curve::set_point(float t, float val)
nuclear@4 8 {
nuclear@4 9 uint16_t x = INDEX(CLAMP(t, 0.0, 1.0));
nuclear@4 10 set_point_int(x, val);
nuclear@4 11 }
nuclear@4 12
nuclear@4 13 static bool cpcmp(const CurvePoint &a, const CurvePoint &b)
nuclear@4 14 {
nuclear@4 15 return a.t_int < b.t_int;
nuclear@4 16 }
nuclear@4 17
nuclear@4 18 void Curve::set_point_int(uint16_t ti, float val)
nuclear@4 19 {
nuclear@4 20 CurvePoint *p = get_point_at(ti);
nuclear@4 21 if(p) {
nuclear@4 22 p->value = val;
nuclear@4 23 } else {
nuclear@4 24 CurvePoint p;
nuclear@4 25 p.t_int = ti;
nuclear@4 26 p.value = val;
nuclear@4 27 cp.push_back(p);
nuclear@4 28 std::sort(cp.begin(), cp.end(), cpcmp);
nuclear@4 29 }
nuclear@4 30 }
nuclear@4 31
nuclear@4 32 bool Curve::delete_point(uint16_t ti)
nuclear@4 33 {
nuclear@4 34 int sz = (int)cp.size();
nuclear@4 35 for(int i=0; i<sz; i++) {
nuclear@4 36 if(cp[i].t_int == ti) {
nuclear@4 37 cp.erase(cp.begin() + i);
nuclear@4 38 return true;
nuclear@4 39 }
nuclear@4 40 }
nuclear@4 41 return false;
nuclear@4 42 }
nuclear@4 43
nuclear@4 44 CurvePoint *Curve::get_point(int idx)
nuclear@4 45 {
nuclear@7 46 if(idx < 0 || idx >= (int)cp.size()) {
nuclear@4 47 return 0;
nuclear@4 48 }
nuclear@4 49 return &cp[idx];
nuclear@4 50 }
nuclear@4 51
nuclear@4 52 const CurvePoint *Curve::get_point(int idx) const
nuclear@4 53 {
nuclear@7 54 if(idx < 0 || idx >= (int)cp.size()) {
nuclear@4 55 return 0;
nuclear@4 56 }
nuclear@4 57 return &cp[idx];
nuclear@4 58 }
nuclear@4 59
nuclear@4 60 int Curve::get_num_points() const
nuclear@4 61 {
nuclear@4 62 return (int)cp.size();
nuclear@4 63 }
nuclear@4 64
nuclear@4 65 CurvePoint *Curve::get_point_at(uint16_t ti)
nuclear@4 66 {
nuclear@4 67 int sz = (int)cp.size();
nuclear@4 68 for(int i=0; i<sz; i++) {
nuclear@4 69 if(cp[i].t_int == ti) {
nuclear@4 70 return &cp[i];
nuclear@4 71 }
nuclear@4 72 }
nuclear@4 73 return 0;
nuclear@4 74 }
nuclear@4 75
nuclear@4 76 const CurvePoint *Curve::get_point_at(uint16_t ti) const
nuclear@4 77 {
nuclear@4 78 int sz = (int)cp.size();
nuclear@4 79 for(int i=0; i<sz; i++) {
nuclear@4 80 if(cp[i].t_int == ti) {
nuclear@4 81 return &cp[i];
nuclear@4 82 }
nuclear@4 83 }
nuclear@4 84 return 0;
nuclear@4 85 }
nuclear@4 86
nuclear@4 87 float Curve::value(float t) const
nuclear@4 88 {
nuclear@4 89 uint16_t x = INDEX(CLAMP(t, 0.0, 1.0));
nuclear@4 90 return value_int(x);
nuclear@4 91 }
nuclear@4 92
nuclear@4 93 float Curve::value_int(uint16_t ti) const
nuclear@4 94 {
nuclear@4 95 CurvePoint p = { ti, 0 };
nuclear@4 96 std::vector<CurvePoint>::const_iterator it;
nuclear@4 97 it = std::lower_bound(cp.begin(), cp.end(), p, cpcmp);
nuclear@4 98 if(ti >= it->t_int || it == cp.begin()) {
nuclear@4 99 return it->value;
nuclear@4 100 }
nuclear@4 101
nuclear@4 102 std::vector<CurvePoint>::const_iterator prev = it - 1;
nuclear@4 103
nuclear@4 104 float t = (float)(ti - prev->t_int) / (float)(it->t_int - prev->t_int);
nuclear@4 105 return prev->value + (it->value - prev->value) * t;
nuclear@4 106 }