So I’ve been trying to manually code a b-spline for a set of any number of user defined points, but I’ve hit a bit of a snag when it comes to the actually coding part of it. I first tested it with a specific knot vector and time value, t, as an example and it matched up for the most part. However, now that I’m trying to do it from a span from t = 0 to 1, it’s suddenly stopped working as I expected. I have tried to checking each individual array manually by printing them as they come and despite the fact that the N array has values in it, I can’t seem to get the point array to have values no matter what I’ve tried, and the line function just doesn’t work at all because of it. I’ve looked through it several times, and I am at a loss for what it is I’m missing or needs work so if anyone could just point out what it is the problem in the code would be very helpful. For context, I’ve included both the main B-spline code as well as the code that creates the knot vector below.
function drawBSpline()
{
stroke('white');
strokeWeight(1);
p = 2;
l = pointArray.length;
posx = []; posy = [];
um = knotVector(l,p);
for (var t = 0; t < 1.001; t += 0.01){
if (t == 0){
posx[t] = pointArray[0].x;
posy[t] = pointArray[0].y;
}
if (t == 1){
posx[t] = pointArray[pointArray.length - 1].x;
posy[t] = pointArray[pointArray.length - 1].y;
}
for (var f = 0; f < um.length; f++){
if(t < um[f]){
N = make2DArray(f,p+1);
break;
}
}
for (var d = 0; d < p+1; d++){
if (d == 0){
for (var i = 0; i < um.length; i++){
if (t >= um[i] && t < um[i+1]){
N[d][i] = 1;
}
else if (t == 0){
N[d][0] = 1;
for (var i = 1; i < um.length - p + 1; i++){
N[d][i] = 0;
}
break;
}
else if (t == 1){
N[d][um.length - p] = 1;
for (j = um.length - p - 1; j >= 0; j--){
N[d][j] = 0;
}
break;
}
else if (i > f+1){
break;
}
else {
N[d][i] = 0;
}
}
}
else {
for (var i = 0; i < um.length; i++){
a1 = (t - um[i]) / (um[i+d] - um[i]);
a2 = (um[i+d+1] - t) / (um[i+d+1] - um[i+1]);
if (a1 == Infinity || a1 == -Infinity){
a1 = 0;
}
if (a2 == Infinity || a2 == -Infinity){
a2 = 0;
}
if (i > f+1){
break;
}
N[d][i] = a1*N[d-1][i] + a2*N[d-1][i+1];
}
}
}
for (var i = 0; i < pointArray.length; i++){
posx[t] += pointArray[i].x * N[p][i];
posy[t] += pointArray[i].y * N[p][i];
}
}
for (var x = 0; x < posx.length-1; x++){
line(posx[x],posy[x],posx[x+1],posy[x+1])
}
}
function knotVector(l,p){
u = new Array(l+p+1);
if (u.length < 2*(p+1)){
return false;
}
for (var c = 0; c < u.length; c++){
if (c <= p){
u[c] = 0;
}
else if (c >= u.length - p - 1){
u[c] = 1;
}
else {
u[c] = (c - p) / (u.length - 2*p - 1);
}
}
return u;
}