mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-26 09:44:32 +02:00
B-Spline
This commit is contained in:
82
lib/spline.js
Normal file
82
lib/spline.js
Normal file
@@ -0,0 +1,82 @@
|
||||
// https://github.com/thibauts/b-spline
|
||||
module.exports = function interpolate(t, degree, points, knots, weights, result, scaled) {
|
||||
|
||||
var i,j,s,l; // function-scoped iteration variables
|
||||
var n = points.length; // points count
|
||||
var d = points[0].length; // point dimensionality
|
||||
|
||||
if(degree < 1) throw new Error('degree must be at least 1 (linear)');
|
||||
if(degree > (n-1)) throw new Error('degree must be less than or equal to point count - 1');
|
||||
|
||||
if(!weights) {
|
||||
// build weight vector of length [n]
|
||||
weights = [];
|
||||
for(i=0; i<n; i++) {
|
||||
weights[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!knots) {
|
||||
// build knot vector of length [n + degree + 1]
|
||||
var knots = [];
|
||||
for(i=0; i<n+degree+1; i++) {
|
||||
knots[i] = i;
|
||||
}
|
||||
} else {
|
||||
if(knots.length !== n+degree+1) throw new Error('bad knot vector length');
|
||||
}
|
||||
|
||||
var domain = [
|
||||
degree,
|
||||
knots.length-1 - degree
|
||||
];
|
||||
|
||||
var low = knots[domain[0]];
|
||||
var high = knots[domain[1]];
|
||||
|
||||
// remap t to the domain where the spline is defined
|
||||
if (!scaled) {
|
||||
t = t * (high - low) + low;
|
||||
}
|
||||
|
||||
if(t < low || t > high) throw new Error('out of bounds');
|
||||
|
||||
// find s (the spline segment) for the [t] value provided
|
||||
for(s=domain[0]; s<domain[1]; s++) {
|
||||
if(t >= knots[s] && t <= knots[s+1]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// convert points to homogeneous coordinates
|
||||
var v = [];
|
||||
for(i=0; i<n; i++) {
|
||||
v[i] = [];
|
||||
for(j=0; j<d; j++) {
|
||||
v[i][j] = points[i][j] * weights[i];
|
||||
}
|
||||
v[i][d] = weights[i];
|
||||
}
|
||||
|
||||
// l (level) goes from 1 to the curve degree + 1
|
||||
var alpha;
|
||||
for(l=1; l<=degree+1; l++) {
|
||||
// build level l of the pyramid
|
||||
for(i=s; i>s-degree-1+l; i--) {
|
||||
alpha = (t - knots[i]) / (knots[i+degree+1-l] - knots[i]);
|
||||
|
||||
// interpolate each component
|
||||
for(j=0; j<d+1; j++) {
|
||||
v[i][j] = (1 - alpha) * v[i-1][j] + alpha * v[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// convert back to cartesian and return
|
||||
var result = result || [];
|
||||
for(i=0; i<d; i++) {
|
||||
result[i] = v[s][i] / v[s][d];
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
Reference in New Issue
Block a user