一、二维点C++实现:
SplineInterpolation.cpp
#include "SplineInterpolation.h"// find the index i where xn >= x_i[i]int FindPositionID_0(float *x_i, float xn, int InputDataLen, float InterplotGap){
#define X0_i_FirstPixel 1.0f int i = xn - X0_i_FirstPixel; return i;}// find the index i where xn >= x_i[i]int FindPositionID_search(float *x_i, float xn, int InputDataLen, float UserPara){
int i; for (i = 0; i < InputDataLen; i++) {
if (xn >= x_i[i]) {
break; } } return i;}
SplineInterpolation.h
#pragma once// find the index i where xn >= x_i[i]int FindPositionID_search(float *x_i, float xn, int InputDataLen, float UserPara);int FindPositionID_0(float *x_i, float xn, int InputDataLen, float InterplotGap);template <int InputDataLen, int OutputDataLen>void InterplotData(float *x_i, float *x_o, float *y_o, float *An, float *Bn, float *Cn, float *Dn, int(*FindPositionID)(float *x_i, float xn, int InputDataLen, float UserPara), float UserPara);template <int InputDataLen>void ConstractSplineLinearEquations(float *A, float *b, float *x_i, float *y_i);template <int DataLen>void SolveSplineEquations(float *A, float *b, float *x);// the FindPositionID is the function to find the index i where xn >= x_i[i]// the UserPara the para to send to FindPositionID// the input of xi must be sortedtemplate <int InputDataLen, int OutputDataLen>void SplineInterpolation(float *x_i, float *y_i, float *x_o, float *y_o, int(*FindPositionID)(float *x_i, float xn, int InputDataLen, float UserPara), float UserPara){
float An[InputDataLen]; float Bn[InputDataLen]; float Cn[InputDataLen]; float Dn[InputDataLen]; // initilize for (int i = 0; i < InputDataLen; i++) {
An[i] = y_i[i]; } // sove linear equations float A[InputDataLen*InputDataLen]; float b[InputDataLen]; ConstractSplineLinearEquations(A, b, x_i, y_i); // solve Cn SolveSplineEquations(A, b, Cn); // solve Bn and Dn for (int i = 0; i1; i++) {
float hi = x_i[i + 1] - x_i[i]; Bn[i] = 1 / hi*(An[i + 1] - An[i]) - hi / 3 * (2 * Cn[i] + Cn[i + 1]); Dn[i] = (Cn[i + 1] - Cn[i]) / (3 * hi); } // yn(i) = An(ParaSet) + Bn(ParaSet)*(curx-xi) + Cn(ParaSet)*(curx-xi)^2 + Dn(ParaSet)*(curx-xi)^3; InterplotData (x_i, x_o, y_o, An, Bn, Cn, Dn, FindPositionID, UserPara);}template <int InputDataLen, int OutputDataLen>void InterplotData(float *x_i, float *x_o, float *y_o, float *An, float *Bn, float *Cn, float *Dn, int(*FindPositionID)(float *x_i, float xn, int InputDataLen, float UserPara), float UserPara){
int ParaSet = 0; for (int i = 0; i < OutputDataLen; i++) {
float xn = x_o[i]; ParaSet = FindPositionID(x_i, xn, InputDataLen, UserPara); if (ParaSet < 0)ParaSet = 0; if (ParaSet >= InputDataLen - 1)ParaSet = InputDataLen - 2;// printf("ParaSet:%d\n", ParaSet); float xi = x_i[ParaSet];// printf("xn xi:%f %f\n", xn, xi); y_o[i] = An[ParaSet] + Bn[ParaSet] * (xn - xi) + Cn[ParaSet] * (xn - xi)*(xn - xi) + Dn[ParaSet] * (xn - xi)*(xn - xi)*(xn - xi); }}template <int InputDataLen>void ConstractSplineLinearEquations(float *A, float *b, float *x_i, float *y_i){
float(*pA)[InputDataLen] = (float(*)[InputDataLen])A; // for parameter array // for (int r = 0; r {
for (int c = 0; c {
pA[r][c] = 0; } } // construct A pA[0][0] = 1; pA[InputDataLen - 1][InputDataLen - 1] = 1; for (int i = 1; i < InputDataLen - 1; i++) {
float h0 = x_i[i] - x_i[i - 1]; float h1 = x_i[i + 1] - x_i[i]; pA[i][i - 1] = h0; pA[i][i] = 2 * (h0 + h1); pA[i][i + 1] = h1; } // construct b b[0] = 0; b[InputDataLen - 1] = 0; for (int i = 1; i1; i++) {
float h0 = x_i[i] - x_i[i - 1]; float h1 = x_i[i + 1] - x_i[i]; float a0 = y_i[i - 1]; float a1 = y_i[i]; float a2 = y_i[i + 1]; b[i] = 3 / h1*(a2 - a1) - 3 / h0*(a1 - a0); }}template <int DataLen>void SolveSplineEquations(float *A, float *b, float *x){