javascript Spline代码
代码是通过网上一个winform代码中提取修改而来的。后转为javascript 版本。
/* points = new Array(); points.push({x:1,y:2}); */ function Spline(points) { var NewArrayFloat = function(n) { var arr = new Array(n); for (var i = 0; i < n; i++) { arr[i] = 0.0; } return arr; } /* C# (float[] sub, float[] diag, float[] sup, ref float[] b, int n) Js return float[] b; */ var solveTridiag = function(sub, diag, sup, b, n) { /* solve linear system with tridiagonal n by n matrix a using Gaussian elimination *without* pivoting where a(i,i-1) = sub[i] for 2<=i<=n a(i,i) = diag[i] for 1<=i<=n a(i,i+1) = sup[i] for 1<=i<=n-1 (the values sub[1], sup[n] are ignored) right hand side vector b[1:n] is overwritten with solution NOTE: 1...n is used in all arrays, 0 is unused */ var i; /*factorization and forward substitution */ for (i = 2; i <= n; i++) { sub[i] = sub[i] / diag[i - 1]; diag[i] = diag[i] - sub[i] * sup[i - 1]; b[i] = b[i] - sub[i] * b[i - 1]; } b[n] = b[n] / diag[n]; for (i = n - 1; i >= 1; i--) { b[i] = (b[i] - sup[i] * b[i + 1]) / diag[i]; } return b; } var resultPoint = new Array(); var precision = 10; var np = points.length; var yCoords = NewArrayFloat(np); var xCoords = NewArrayFloat(np); var x; var y; var oldy = 0; var oldx = 0; var npp = np * precision; // draw a border around the canvas if (np > 0) { // draw the control points for (var i = 0; i < np; i++) { var p = { x: points[i].x, y: points[i].y }; xCoords[i] = p.x; yCoords[i] = p.y; } if (np > 1) { var a = new NewArrayFloat(np); var x1; var x2; var h = new NewArrayFloat(np); for (var i = 1; i <= np - 1; i++) { h[i] = xCoords[i] - xCoords[i - 1]; } if (np > 2) { var sub = NewArrayFloat(np - 1); var diag = NewArrayFloat(np - 1); var sup = NewArrayFloat(np - 1); for (var i = 1; i <= np - 2; i++) { diag[i] = (h[i] + h[i + 1]) / 3; sup[i] = h[i + 1] / 6; sub[i] = h[i] / 6; a[i] = (yCoords[i + 1] - yCoords[i]) / h[i + 1] - (yCoords[i] - yCoords[i - 1]) / h[i]; } //C# CODE param [a] = [ref a]; a = solveTridiag(sub, diag, sup, a, np - 2); } // note that a[0]=a[np-1]=0 oldx = xCoords[0]; oldy = yCoords[0]; resultPoint.push({ x: oldx, y: oldy }); for (var i = 1; i <= np - 1; i++) { // loop over intervals between nodes for (var j = 1; j <= precision; j++) { x1 = (h[i] * j) / precision; x2 = h[i] - x1; y = ((-a[i - 1] / 6 * (x2 + h[i]) * x1 + yCoords[i - 1]) * x2 + (-a[i] / 6 * (x1 + h[i]) * x2 + yCoords[i]) * x1) / h[i]; x = xCoords[i - 1] + x1; resultPoint.push({ x: x, y: y }); oldx = x; oldy = y; } } } } return resultPoint; }