00001
00002 #ifndef JMATH_INTERPOL_HPP
00003 #define JMATH_INTERPOL_HPP
00004
00005 #include <math.h>
00006
00007 namespace jafar {
00008 namespace jmath {
00009
00010
00025 static inline void parabolicInterpolation(double x0, double y0, double x1, double y1, double x2, double y2, double & extremum_x, double & extremum_y, double &a, double &b, double &c)
00026 {
00027 double x01 = x0-x1, x02 = x0-x2, x12 = x1-x2;
00028 double t0 = y0/(x01*x02), t1 = y1/(x01*x12), t2 = y2/(x02*x12);
00029 a = t0 - t1 + t2;
00030 b = -((x1+x2)*t0 - (x0+x2)*t1 + (x0+x1)*t2);
00031 c = x1*x2*t0 - x0*x2*t1 + x0*x1*t2;
00032 if (a == 0.0) { extremum_x = extremum_y = 0.0; return; }
00033
00034 extremum_x = -b/(a*2.0);
00035 extremum_y = c-b*b/(a*4.0);
00036 }
00037
00044 static inline void parabolicInterpolation(double x0, double y0, double x1, double y1, double x2, double y2, double & extremum_x, double & extremum_y)
00045 {
00046 double tempa, tempb, tempc;
00047 parabolicInterpolation(x0, y0, x1, y1, x2, y2, extremum_x, extremum_y, tempa, tempb, tempc);
00048 }
00049
00056 static inline void parabolicInterpolation(double x0, double y0, double x1, double y1, double x2, double y2, double & extremum_x)
00057 {
00058 double x01 = x0-x1, x02 = x0-x2, x12 = x1-x2;
00059 double t0 = y0/(x01*x02), t1 = y1/(x01*x12), t2 = y2/(x02*x12);
00060 double a = t0 - t1 + t2;
00061 if (a == 0.0) { extremum_x = 0.0; return; }
00062 double b = -((x1+x2)*t0 - (x0+x2)*t1 + (x0+x1)*t2);
00063
00064 extremum_x = -b/(a*2.0);
00065 }
00066
00073 static inline void parabolicInterpolation(double y0, double y1, double y2, double & extremum_x, double & extremum_y, double & a)
00074 {
00075
00076
00077
00078 a = (y0+y2)/2.0 - y1;
00079 if (a == 0.0) { extremum_x = extremum_y = 0.0; return; }
00080 double b = (y2-y0)/2.0;
00081 double c = y1;
00082
00083 extremum_x = -b/(a*2.0);
00084 extremum_y = c-b*b/(a*4.0);
00085 }
00086
00093 static inline void parabolicInterpolation(double y0, double y1, double y2, double & extremum_x, double & extremum_y)
00094 {
00095 double tempa;
00096 parabolicInterpolation(y0, y1, y2, extremum_x, extremum_y, tempa);
00097 }
00098
00105 static inline void parabolicInterpolation(double y0, double y1, double y2, double & extremum_x)
00106 {
00107
00108
00109
00110 double a = (y0+y2)/2.0 - y1;
00111 if (a == 0.0) { extremum_x = 0.0; return; }
00112 double b = (y2-y0)/2.0;
00113
00114 extremum_x = -b/(a*2.0);
00115 }
00116
00120 static inline double parabolWidth(double a, double b, double c, double y0=0)
00121 {
00122 c -= y0;
00123 double delta = b*b-4.0*a*c;
00124 if (delta <= 0) return 0; else return sqrt(delta)/(2*fabs(a));
00125 }
00126
00127
00128
00132 class CubicInterpolate
00133 {
00134 double a0,a1,a2,a3;
00135 double m1,m2,y1,y2,x1,x2;
00136 bool constant;
00137
00138 public:
00144 inline void setSegment(double x0, double y0, double x1, double y1, double x2, double y2,double x3, double y3)
00145 {
00146
00147
00148
00149 m1 = (y2-y1)/(2) + (x2-x1)*(y1-y0)/(2*(x1-x0));
00150 m2 = (x2-x1)*(y3-y2)/(2*(x3-x2)) + (y2-y1)/(2);
00151 this->y1 = y1;
00152 this->y2 = y2;
00153 this->x1 = x1;
00154 this->x2 = x2;
00155 constant = false;
00156 }
00162 inline void setSegment(double y0,double y1,double y2,double y3)
00163 {
00164 a0 = y3 - y2 - y0 + y1;
00165 a1 = y0 - y1 - a0;
00166 a2 = y2 - y0;
00167 a3 = y1;
00168 constant = true;
00169 }
00170
00174 inline double interpolateCoeff(double t)
00175 {
00176 double t2 = t*t;
00177 if (constant)
00178 {
00179 return a0*t*t2 + a1*t2 + a2*t + a3;
00180 } else
00181 {
00182 double t3 = t2*t;
00183
00184 double h00 = 2*t3 - 3*t2 + 1;
00185 double h10 = t3 - 2*t2 + t;
00186 double h01 = -2*t3 + 3*t2;
00187 double h11 = t3 - t2;
00188
00189
00190 return h00*y1 + h10*m1 + h01*y2 + h11*m2;
00191 }
00192 }
00193
00197 inline double interpolateValue(double x)
00198 {
00199 if (constant)
00200 {
00201 return interpolateCoeff(x);
00202 } else
00203 {
00204 double t = (x - x1) / (x2 - x1);
00205 return interpolateCoeff(t);
00206 };
00207 }
00208
00209 };
00210
00211
00212
00213
00214 }}
00215
00216 #endif
00217