void gen_interp(struct curve_points *plot) { spline_coeff *sc; double *bc; struct coordinate *new_points; int i, curves; int first_point, num_points; curves = num_curves(plot); new_points = gp_alloc((samples_1 + 1) * curves * sizeof(struct coordinate), "interpolation table"); first_point = 0; for (i = 0; i < curves; i++) { num_points = next_curve(plot, &first_point); switch (plot->plot_smooth) { case SMOOTH_CSPLINES: sc = cp_tridiag(plot, first_point, num_points); do_cubic(plot, sc, first_point, num_points, new_points + i * (samples_1 + 1)); free(sc); break; case SMOOTH_ACSPLINES: sc = cp_approx_spline(plot, first_point, num_points); do_cubic(plot, sc, first_point, num_points, new_points + i * (samples_1 + 1)); free(sc); break; case SMOOTH_BEZIER: case SMOOTH_SBEZIER: bc = cp_binomial(num_points); do_bezier(plot, bc, first_point, num_points, new_points + i * (samples_1 + 1)); free((char *) bc); break; case SMOOTH_KDENSITY: do_kdensity( plot, first_point, num_points, new_points + i * (samples_1 + 1)); break; default: /* keep gcc -Wall quiet */ ; } new_points[(i + 1) * (samples_1 + 1) - 1].type = UNDEFINED; first_point += num_points; } free(plot->points); plot->points = new_points; plot->p_max = curves * (samples_1 + 1); plot->p_count = plot->p_max - 1; return; }
void bezier_interp(std::vector<T> x_in, std::vector<T> y_in, std::vector<T> &x_out, std::vector<T> &y_out, int fp, int np, int ns) { /// This function interpolates with a bezier function of degree n, /// where n is the number of datapoints. /// /// x_in,y_in Input datapoints /// x_out,y_out The output datapoints for Bezier function /// fp First datapoints (default=0) /// np Number of datapoints (default=x_in.size()) /// ns Number of samples (default=np) if (x_in.size()!=y_in.size()) { std::cout << "BEZIER Error: x_in & y_in have different dimensions.\n"; exit(EXIT_FAILURE); } if (np==-1) np=x_in.size(); if (ns==-1) ns=np; if (np>x_in.size()-fp) { std::cout << "BEZIER Error: number of datapoints is greater than the size of input vectors.\n"; exit(EXIT_FAILURE); } if (x_out.size()!=ns || y_out.size()!=ns) { std::cout << "BEZIER Error: The dimensions of output bezier vector must be = n_samples.\n"; exit(EXIT_FAILURE); } double *bc = cp_binomial(np); for (int i=0; i<ns; i++) { double sr = (double)i/(double)(ns-1); unsigned int n = np-1; float px=0., py=0.; if (sr == 0.0) { px = x_in[fp]; py = y_in[fp]; } else if (sr == 1.0) { px = x_in[fp+n]; py = y_in[fp+n]; } else { double log_dsr_to_the_n = n*log(1-sr); double log_sr_over_dsr = log(sr)-log(1-sr); for (unsigned j=0; j<=n; j++) { double u = exp(bc[j]+log_dsr_to_the_n+j*log_sr_over_dsr); px += x_in[j+fp]*u; py += y_in[j+fp]*u; } } x_out[i]=px; y_out[i]=py; } delete [] bc; }