| 1157 | return y1 * (1.0 - factor) + y2 * factor; |
| 1158 | } |
| 1159 | static double IntegrateInterpolated(double y1, double y2, double time, bool logarithmic) |
| 1160 | { |
| 1161 | // Calculates: integral(interpolate(y1, y2, x), x = 0 .. time) |
| 1162 | // Integrating logarithmic interpolated segments is surprisingly simple. You can check this formula here: |
| 1163 | // http://www.wolframalpha.com/input/?i=integrate+10%5E%28log10%28y1%29*%28T-x%29%2FT%2Blog10%28y2%29*x%2FT%29+from+0+to+T |
| 1164 | // Again, the base you use for interpolation is irrelevant, the formula below should always use the natural |
| 1165 | // logarithm (i.e. 'log' in C/C++). If the denominator is too small, it's better to use linear interpolation |
| 1166 | // because the rounding errors would otherwise get too large. The threshold value is 1.0e-5 because at that |
| 1167 | // point the rounding errors become larger than the difference between linear and logarithmic (I tested this in Octave). |
| 1168 | if(logarithmic) |
| 1169 | { |
| 1170 | double l = log(y1 / y2); |
| 1171 | if(fabs(l) < 1.0e-5) // fall back to linear interpolation |
| 1172 | return (y1 + y2) * 0.5 * time; |
| 1173 | return (y1 - y2) / l * time; |
| 1174 | } |
| 1175 | else |
| 1176 | { |
| 1177 | return (y1 + y2) * 0.5 * time; |
| 1178 | } |
| 1179 | } |
| 1180 | static double IntegrateInverseInterpolated(double y1, double y2, double time, bool logarithmic) |
| 1181 | { |
| 1182 | // Calculates: integral(1 / interpolate(y1, y2, x), x = 0 .. time) |