├── .gitignore ├── LICENSE ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | test* 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Thibaut Séguy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cubic-hermite-spline 2 | ==================== 3 | ### Cubic Hermite spline interpolation 4 | 5 | [Cubic Hermite spline](http://en.wikipedia.org/wiki/Cubic_Hermite_spline) interpolation of points / tangents in any dimension with optional derivative computation. The interpolator can also take a knot-like vector as an optional parameter, which may be useful to enforce time at control points when used for position / velocity interpolation. 6 | 7 | 8 | Install 9 | ------- 10 | 11 | ```bash 12 | $ npm install cubic-hermite-spline 13 | ``` 14 | 15 | Example 16 | ------- 17 | 18 | Basic usage 19 | 20 | ```javascript 21 | var hermite = require('cubic-hermite-spline'); 22 | 23 | var points = [ 24 | [-1, 0], 25 | [ 0, 0], 26 | [ 1, 0] 27 | ]; 28 | 29 | var tangents = [ 30 | [1, 1], 31 | [0, 1], 32 | [1, 1] 33 | ]; 34 | 35 | for(var t=0; t<1; t+=0.01) { 36 | var point = hermite(t, points, tangents); 37 | var tangent = hermite(t, points, tangents, null, true); 38 | } 39 | ``` 40 | 41 | 42 | 43 | 44 | With a knot vector 45 | 46 | ```javascript 47 | var hermite = require('cubic-hermite-spline'); 48 | 49 | var points = [ 50 | [-1, 0], 51 | [ 0, 0], 52 | [ 1, 0] 53 | ]; 54 | 55 | var tangents = [ 56 | [1, 1], 57 | [0, 1], 58 | [1, 1] 59 | ]; 60 | 61 | var knots = [ 62 | 0, 1.5, 2 63 | ]; 64 | 65 | for(var t=0; t<1; t+=0.01) { 66 | var point = hermite(t, points, tangents); 67 | var tangent = hermite(t, points, tangents, knots, true); 68 | } 69 | ``` 70 | 71 | 72 | 73 | 74 | Usage 75 | ----- 76 | 77 | ### `hermite(t, points, tangents[, knots, derivative, result])` 78 | 79 | Computes the interpolation at `t` for the provided set of points and tangents, and optional knots. 80 | 81 | * `t` position along the curve: in the [0, 1] range for regular use, and [0, last-knot-value] when using knots 82 | * `points` vectors to interpolate 83 | * `tangents` tangents at provided points 84 | * `knots` enforced values of `t` at provided points 85 | * `derivative` if true return the tangeant at `t` instead of the position 86 | * `result` preallocated array in which the result will be stored (to avoid garbage collection) 87 | 88 | **Returns** the interpolated vector 89 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function interpolate(t, points, tangents, knots, derivative, result) { 4 | 5 | var n = points.length; // number or points / tangents / knots 6 | var d = points[0].length; // vector dimensionality 7 | var v = result || new Array(d); // destination vector 8 | 9 | if(knots) { 10 | // find knot interval for t 11 | for(var i=0; i= knots[i] && t <= knots[i+1]) { 13 | break; 14 | } 15 | } 16 | 17 | if(i === n-1) throw new Error('out of bounds'); 18 | 19 | var i0 = i; 20 | var i1 = i + 1; 21 | var k0 = knots[i0]; 22 | var k1 = knots[i1]; 23 | var scale = k1 - k0; 24 | 25 | t = (t - k0) / scale; 26 | 27 | } else { 28 | 29 | var t = t * (n - 1); // rescale t to [0, n-1] 30 | var i0 = t|0; // truncate 31 | var i1 = i0 + 1; 32 | 33 | if(i0 > n-1) throw new Error('out of bounds'); 34 | if(i0 === n-1) i1 = i0; 35 | 36 | var scale = i1 - i0; 37 | 38 | t = (t - i0) / scale; 39 | } 40 | 41 | if(derivative) { 42 | var t2 = t * t; 43 | var h00 = 6 * t2 - 6 * t; 44 | var h10 = 3 * t2 - 4 * t + 1; 45 | var h01 = - 6 * t2 + 6 * t; 46 | var h11 = 3 * t2 - 2 * t; 47 | } else { 48 | var t2 = t * t; 49 | var it = 1 - t; 50 | var it2 = it * it; 51 | var tt = 2 * t; 52 | var h00 = (1 + tt) * it2; 53 | var h10 = t * it2; 54 | var h01 = t2 * (3 - tt); 55 | var h11 = t2 * (t - 1); 56 | } 57 | 58 | for(var i=0; i