Recently need to use interpolation, but always feel that the linear interpolation is worth it too hard, so want to see three times how to do spline curve. There are a lot of articles about algorithms and program implementations. The main purpose of this article is to
- Help yourself to understand, solidify
- The existing code is not implemented on the Unity platform, so the code is relatively cumbersome, and it's further simplified
I understand that the piecewise three spline solution is:
- Known: n points, n-1 three-th equation (a+bx+cx^2+dx^3), and these three-order equations 21 and second derivative continuous, these three-th equation is of course at the known point is also continuous
- The second derivative of the first order is continuous, that is, in the middle of the connection point (Total n-2), the derivative of the two equations is equal
- The equations are better understood at known points, and a line runs through all points.
- So the known conditions are a bit: N, the first derivative continuous n-2, second-order derivative continuous n-2, point continuous n-2, a total of 4n-6
- Unknown: n-1 The coefficients of the three-time equation abcd, there's a 4n-4.
- Known to be less than the unknown two conditions, so there will be a variety of boundary settings, we use natural boundaries, that is, assuming that the boundary does not have force to bend the curve, is basically like PS inside the curve of the end of the way without limiting direction. With the boundary conditions set, both the known and the unknown are 4n-4 and can be solved
How to solve it ... If you are interested, you can read this article:
Http://www.cnblogs.com/xpvincent/archive/2013/01/26/2878092.html
After this equation group is written in matrix form, it can be found that the TDMA algorithm is able to calculate, the tube He TDMA algorithm is what it ... Names don't matter.
Interested in the TDMA algorithm, you can look at this article:
Http://www.cnblogs.com/xpvincent/archive/2013/01/25/2877411.html
If you feel bored to see the three-time curve algorithm, at least still should look at the TDMA algorithm, or the next look at the code is also a dazzling flower
Currently just do two-dimensional interpolation, three-dimensional words, it is estimated that the XY plane to come once, and then the XZ plane again?
Put the code below, because still just experiment, so the code is not very good to write ...
float[] x={1.4f, 3f,4f,5.5f,6.5f,7.4f}; float[] y={2.3f,4.4f,5.6f, 8f,10f,10.4f}; float[] A; float[] b; float[] C; float[] D; float[] H; float[] xext; float[] yext;
This paragraph is only 6 points of information written in, ABCD is the TDMA algorithm and three curve interpolation process will be used repeatedly, so directly in the class declaration, H is the three curve interpolation algorithm will be used in the X component of the length between each segment.
ABCD and XY are all 6 length,h are 5
Xext and Yext are the point coordinates after the expansion of the stored interpolation.
Static float[] TDMA (float[] TA,float[] TB,float[] TC,float[] tx) { intn=TX. Length; tc[0]=tc[0]/tb[0]; tx[0]=tx[0]/tb[0]; for(intI=1; i<n;i++){ floatm=1/(tb[i]-ta[i]*tc[i-1]); Tc[i]=tc[i]*m; Tx[i]= (tx[i]-ta[i]*tx[i-1])*m; } for(inti=n-2;i>0; i--) {Tx[i]=tx[i]-tc[i]*tx[i+1]; } returnTX; }
TDMA algorithm, the program is basically taken from the quoted article.
Well, if I hadn't seen what the TDMA algorithm was, I really didn't know what to say.
This TA,TB,TC corresponds to the left of the left matrix, the middle right of the upper three Slash, TX corresponds to the right side of the equal vector.
It's written for convenience, but it's straightforward to look a little counter-intuitive. Let's see the algorithm first.
Calculation of the coefficients of each segment of the three-time curve:
Private voidCinterp (float[] x,float[] y) {intn=x.length; float[] m=New float[n]; H=New float[N-1]; A=New float[n]; b=New float[n]; C=New float[n]; D=New float[n]; for(intI=0; i<n-1; i++) {H[i]=x[i+1]-X[i]; } a[0]=0; b[0]=1; c[0]=0; d[0]=0; A[n-1]=0; B[n-1]=1; C[n-1]=0; D[n-1]=0; for(intI=1; i<n-1; i++) {A[i]=h[i-1]; B[i]=2* (h[i-1]+H[i]); C[i]=H[i]; D[i]=6* ((y[i+1]-y[i])/h[i]-(y[i]-y[i-1])/h[i-1]); } m=TDMA (a,b,c,d); for(intI=0; i<n-1; i++) {A[i]=Y[i]; B[i]= (y[i+1]-y[i])/h[i]-h[i]*m[i]/2-h[i]* (m[i+1]-m[i])/6; C[i]=m[i]/2; D[i]= (m[i+1]-m[i])/(6*H[i]); } }
In fact, I do not seem to write a brief.
In this, the ABCD before referencing the TDMA function is represented by the ABCD in the solution matrix
The ABCD after referencing the TDMA function is the coefficient inside the three function, ABCD ...
I'm just too lazy to declare four new arrays ...
In addition, the length of H is also used to obtain, so in the class has been declared, M words outside use, only in method inside the declaration.
When the coefficients are calculated, they are interpolated. I'm here to insert two new points in the middle of every two points.
First insert in x direction:
Private float[] Xinterp (float[] Xin,float[] hin) { float[] xext=New float[(Xin. length-1)*3+1]; intI=0; for(;i< (Xin. length-1); i++) {Xext[i*3]=Xin[i]; Xext[i*3+1]=xin[i]+hin[i]/3; Xext[i*3+2]=xin[i]+hin[i]/3*2; } xext[i*3]=Xin[i]; returnXext; }
And then, according to the X-direction point, Y, since each segment is inserted 2 points, it naturally starts from the starting point every three points with one equation.
Private float[] Yinterp (float[] xex) { float[] yout=New float[Xex. Length]; for(intI=0; I<xex. length;i++) { intSeg= (int) i/3; floath=xex[i]-xex[seg*3]; Yout[i]=a[seg]+b[seg]*h+c[seg]*h*h+d[seg]*h*h*h; } yout[xex. Length-1]=y[y.length-1]; returnyout; }
Then let's look at the effect in scene view:
Start ():
void Start () { cinterp (x, y ); for (int i=0;i< (x.length-1); i++) {// Debug.Log (a[i]+ "," + B[i]+ "," +c[i]+ "," +d[i "); } xext=xinterp (x,h); Yext=yinterp (xext); }
voidOndrawgizmos () {//for (int i=0;i<5;i++) {//Gizmos.drawline (New Vector2 (X[i],y[i]), new Vector2 (x[i+1],y[i+1])); // } for(intI=0;i<6; i++) {Gizmos.drawsphere (NewVector2 (X[i],y[i]),0.1f); } for(intI=0; i<xext.length-1; i++) {Gizmos.drawline (NewVector2 (Xext[i],yext[i]),NewVector2 (xext[i+1],yext[i+1])); } }
By the way, Ondrawgizmos is really debugging magic ah, better than debug.drawline.
Implementation of three spline interpolation curves in unity