120#if SPLINE_BRUTE_FORCE
121#define interpolate_segment interpolate_brute_force
123#define interpolate_segment interpolate_forward_difference
131void cubic_coefficients(
double x1,
double y1,
double x2,
double y2,
132 double k1,
double k2,
133 double& a,
double& b,
double& c,
double& d)
135 double dx = x2 - x1, dy = y2 - y1;
137 a = ((k1 + k2) - 2*dy/dx)/(dx*dx);
138 b = ((k2 - k1)/dx - 3*(x1 + x2)*a)/2;
139 c = k1 - (3*x1*a + 2*b)*x1;
140 d = y1 - ((x1*a + b)*x1 + c)*x1;
146template<
class Po
intPlotter>
148void interpolate_brute_force(
double x1,
double y1,
double x2,
double y2,
149 double k1,
double k2,
150 PointPlotter plot,
double res)
153 cubic_coefficients(x1, y1, x2, y2, k1, k2, a, b, c, d);
156 for (
double x = x1; x <= x2; x += res) {
157 double y = ((a*x + b)*x + c)*x + d;
165template<
class Po
intPlotter>
167void interpolate_forward_difference(
double x1,
double y1,
double x2,
double y2,
168 double k1,
double k2,
169 PointPlotter plot,
double res)
172 cubic_coefficients(x1, y1, x2, y2, k1, k2, a, b, c, d);
174 double y = ((a*x1 + b)*x1 + c)*x1 + d;
175 double dy = (3*a*(x1 + res) + 2*b)*x1*res + ((a*res + b)*res + c)*res;
176 double d2y = (6*a*(x1 + res) + 2*b)*res*res;
177 double d3y = 6*a*res*res*res;
180 for (
double x = x1; x <= x2; x += res) {
182 y += dy; dy += d2y; d2y += d3y;
186template<
class Po
intIter>
193template<
class Po
intIter>
208template<
class Po
intIter,
class Po
intPlotter>
210void interpolate(PointIter p0, PointIter pn, PointPlotter plot,
double res)
215 PointIter p1 = p0; ++p1;
216 PointIter p2 = p1; ++p2;
217 PointIter p3 = p2; ++p3;
220 for (; p2 != pn; ++p0, ++p1, ++p2, ++p3) {
222 if (x(p1) == x(p2)) {
226 if (x(p0) == x(p1) && x(p2) == x(p3)) {
227 k1 = k2 = (y(p2) - y(p1))/(x(p2) - x(p1));
230 else if (x(p0) == x(p1)) {
231 k2 = (y(p3) - y(p1))/(x(p3) - x(p1));
232 k1 = (3*(y(p2) - y(p1))/(x(p2) - x(p1)) - k2)/2;
235 else if (x(p2) == x(p3)) {
236 k1 = (y(p2) - y(p0))/(x(p2) - x(p0));
237 k2 = (3*(y(p2) - y(p1))/(x(p2) - x(p1)) - k1)/2;
241 k1 = (y(p2) - y(p0))/(x(p2) - x(p0));
242 k2 = (y(p3) - y(p1))/(x(p3) - x(p1));
245 interpolate_segment(x(p1), y(p1), x(p2), y(p2), k1, k2, plot, res);
259 PointPlotter(F* arr) : f(arr)
263 void operator ()(
double x,
double y)
270 f[int(x)] = F(y + 0.5);