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 +}