/* Subroutine to generate B-spline basis functions and their derivatives for uniform open knot vectors.
C code for An Introduction to NURBS
by David F. Rogers. Copyright (C) 2000 David F. Rogers,
All rights reserved.
Name: dbasis.c
Language: C
Subroutines called: none
Book reference: Section 3.10, Ex. 3.18, Alg. p. 283
b1 = first term of the basis function recursion relation
b2 = second term of the basis function recursion relation
c = order of the B-spline basis function
d1[] = array containing the derivative of the basis functions
d1[1]) contains the derivative of the basis function associated with B1 etc.
d2[] = array containing the derivative of the basis functions
d2[1] contains the derivative of the basis function associated with B1 etc.
f1 = first term of the first derivative of the basis function recursion relation
f2 = second term of the first derivative of the basis function recursion relation
f3 = third term of the first derivative of the basis function recursion relation
f4 = fourth term of the first derivative of the basis function recursion relation
npts = number of defining polygon vertices
n[] = array containing the basis functions
n[1]) contains the basis function associated with B1 etc.
nplusc = constant -- npts + c -- maximum knot value
s1 = first term of the second derivative of the basis function recursion relation
s2 = second term of the second derivative of the basis function recursion relation
s3 = third term of the second derivative of the basis function recursion relation
s4 = fourth term of the second derivative of the basis function recursion relation
t = parameter value
temp[] = temporary array
x[] = knot vector
*/
#include
#include
dbasis(c,t,npts,x,n,d1,d2)
int c,npts;
int x[];
float t;
float n[],d1[],d2[];
{
int nplusc;
int i,k;
float b1,b2;
float f1,f2,f3,f4;
float s1,s2,s3,s4;
float temp[36]; /* allows for 35 defining polygon vertices */
float temp1[36];
float temp2[36];
nplusc = npts + c;
/* zero the temporary arrays */
for (i = 1; i <= nplusc; i++){
temp[i] = 0.;
temp1[i] = 0.;
temp2[i] = 0.;
}
/* calculate the first order basis functions n[i] */
for (i = 1; i<= nplusc-1; i++){
if (( t >= x[i]) && (t < x[i+1]))
temp[i] = 1;
else
temp[i] = 0;
}
if (t == (float)x[nplusc]){ /* pick up last point */
temp[npts] = 1;
}
/* calculate the higher order basis functions */
for (k = 2; k <= c; k++){
for (i = 1; i <= nplusc-k; i++){
if (temp[i] != 0) /* if the lower order basis function is zero skip the calculation */
b1 = ((t-x[i])*temp[i])/(x[i+k-1]-x[i]);
else
b1 = 0;
if (temp[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
b2 = ((x[i+k]-t)*temp[i+1])/(x[i+k]-x[i+1]);
else
b2 = 0;
/* calculate first derivative */
if (temp[i] != 0) /* if the lower order basis function is zero skip the calculation */
f1 = temp[i]/(x[i+k-1]-x[i]);
else
f1 = 0;
if (temp[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
f2 = -temp[i+1]/(x[i+k]-x[i+1]);
else
f2 = 0;
if (temp1[i] != 0) /* if the lower order basis function is zero skip the calculation */
f3 = ((t-x[i])*temp1[i])/(x[i+k-1]-x[i]);
else
f3 = 0;
if (temp1[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
f4 = ((x[i+k]-t)*temp1[i+1])/(x[i+k]-x[i+1]);
else
f4 = 0;
/* calculate second derivative */
if (temp1[i] != 0) /* if the lower order basis function is zero skip the calculation */
s1 = (2*temp1[i])/(x[i+k-1]-x[i]);
else
s1 = 0;
if (temp1[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
s2 = (-2*temp1[i+1])/(x[i+k]-x[i+1]);
else
s2 = 0;
if (temp2[i] != 0) /* if the lower order basis function is zero skip the calculation */
s3 = ((t-x[i])*temp2[i])/(x[i+k-1]-x[i]);
else
s3 = 0;
if (temp2[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
s4 = ((x[i+k]-t)*temp2[i+1])/(x[i+k]-x[i+1]);
else
s4 = 0;
temp[i] = b1 + b2;
temp1[i] = f1 + f2 + f3 + f4;
temp2[i] = s1 + s2 + s3 + s4;
}
}
/* put in n array */
for (i = 1; i <= npts; i++) {
n[i] = temp[i];
d1[i] = temp1[i];
d2[i] = temp2[i];
}
}