00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef VEE_INTERPOLATORS_H
00021 #define VEE_INTERPOLATORS_H
00022
00023 #include <vector>
00024
00025 #include <string.h>
00026 #include <strings.h>
00027
00030 template <typename T>
00031 class VEE_InterpolationPoint
00032 {
00033 public:
00034 VEE_InterpolationPoint() {}
00035
00036 VEE_InterpolationPoint(const T &value, float time)
00037 : m_value(value), m_time(time) {}
00038
00039 T m_value;
00040 float m_time;
00041 };
00042
00045 template <typename T>
00046 class VEE_LinearInterpolation
00047 {
00048 public:
00049 VEE_LinearInterpolation() : m_index(0) {}
00050 ~VEE_LinearInterpolation() {}
00051
00053 void clear() { m_index = 0; m_points.resize(0); }
00054
00056 inline T getValue(float t)
00057 {
00058 T res;
00059
00060 seekInterval(t);
00061
00062 if(m_index >= m_points.size()) {
00063 bzero(&res, sizeof(res));
00064 return res;
00065 }
00066
00067 if(m_index + 1 == m_points.size()) {
00068 return m_points[m_index].m_value;
00069 }
00070
00071 return interpolate(m_points[m_index], m_points[m_index + 1], t);
00072 }
00073
00076 inline T getValueBisect(float t) const
00077 {
00078 T res;
00079
00080 if(!m_points.size()) {
00081 bzero(&res, sizeof(res));
00082 return res;
00083 }
00084
00085 uint higher = m_points.size() - 1;
00086 uint lower = 0;
00087
00088 while(higher > lower + 1) {
00089 uint center = (higher + lower) >> 1;
00090 if(m_points[center].m_time > t)
00091 higher = center;
00092 else
00093 lower = center;
00094 }
00095
00096 if(m_points[higher].m_time <= t)
00097 return m_points[higher].m_value;
00098
00099 return interpolate(m_points[lower], m_points[higher], t);
00100 }
00101
00103 inline T getValueFast(float t)
00104 {
00105 T res;
00106
00107 seekInterval(t);
00108
00109 if(m_index >= m_points.size()) {
00110 bzero(&res, sizeof(res));
00111 return res;
00112 }
00113
00114 return m_points[m_index].m_value;
00115 }
00116
00118 void appendPoint(const T & v, float t)
00119 {
00120 unsigned s = m_points.size();
00121 if(s) {
00122 if(m_points[s - 1].m_time == t) {
00123 m_points[s - 1].m_value = v;
00124 return;
00125 }
00126
00127 }
00128 m_points.push_back(VEE_InterpolationPoint<T>(v, t));
00129 }
00130
00131 bool atEnd() const
00132 {
00133 if(!m_points.size())
00134 return true;
00135 return m_index + 1 >= m_points.size();
00136 }
00137
00139 unsigned size() { return m_points.size(); }
00140
00141 VEE_InterpolationPoint<T> & getPoint(uint i) { return m_points[i]; }
00142
00144 static inline T interpolate(const VEE_InterpolationPoint<T> & p1,
00145 const VEE_InterpolationPoint<T> & p2,
00146 float t)
00147 {
00148 float diff = p2.m_time - p1.m_time;
00149
00150 if(diff < 1.0e-8)
00151 return p2.m_value;
00152
00153 float mix = (t - p1.m_time) / diff;
00154 return interpolate(p2.m_value, p1.m_value, mix);
00155 }
00156
00161 static inline T interpolate(const T & v1, const T & v2, float mix)
00162 { return v1 * mix + v2 * (1.0 - mix); }
00163
00164 float endTime() const
00165 { return m_points.size() ? m_points[m_points.size()-1].m_time : 0.0f; }
00166
00167 void moveTime(float offset)
00168 { for(uint i=0; i < m_points.size(); i++) m_points[i].m_time += offset; }
00169
00170 protected:
00171
00172 void seekInterval(float t)
00173 {
00174 unsigned n = m_points.size();
00175
00176 while(m_index < n) {
00177
00178 VEE_InterpolationPoint<T> *p = & m_points[m_index];
00179
00180 if(p->m_time < t) {
00181
00182
00183 if(m_index + 1 >= n)
00184 return;
00185 if(m_points[m_index + 1].m_time < t)
00186 m_index++;
00187 else
00188 return;
00189 }
00190 else if(p->m_time > t) {
00191
00192 if(!m_index) return;
00193 m_index--;
00194 }
00195 else
00196 return;
00197 }
00198 }
00199
00200 std::vector<VEE_InterpolationPoint<T> > m_points;
00201 unsigned m_index;
00202 };
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00218
00219 template <typename T>
00220 class VEE_LinearInterpolation2 : public VEE_LinearInterpolation<T>
00221 {
00222 public:
00223 VEE_LinearInterpolation2() : m_time(0.0) {}
00224 ~VEE_LinearInterpolation2() {}
00225
00226 void move(float dt) { m_time += dt; }
00227 void reset(float time = 0.0)
00228 { m_time = time; m_index = 0; seekInterval(time); }
00229
00230 float time() const { return m_time; }
00231
00232 T getValue2() { return getValue(m_time); }
00233
00234 protected:
00235 float m_time;
00236 };
00237
00238 #endif