 # Evaluate basis function given knot vector

Is it possible in C++ using OpenNURBS to evaluate the value of the basis functions given knot vectors and parametric coordinate values for a NURBS surface ?

I am looking for the value of R[i, j] (u, v), in the NURBS formula :

I guess it would be equivalent to build a NURBS surface with all weights being 0 except for one vertex which would have its weight set to 1, however I am looking for a fast and straightforward function to call in the library if it exists.

@dalelear, is this something you can help with?

In the C++ opennurbs SDK there several functions for evaluation of NURBS basis functions.
These two should do the trick.

``````/*
Description:
Evaluate B-spline basis functions

Parameters:
order - [in]
order >= 1
d = degree = order - 1
knot - [in]
array of length 2*d.
Generally, knot <= ... <= knot[d-1] < knot[d] <= ... <= knot[2*d-1].
These are the knots that are active for the span being evaluated.
t - [in]
Evaluation parameter.
Typically knot[d-1] <= t <= knot[d].
In general t may be outside the interval knot[d-1],knot[d]. This can happen
when some type of extrapolation is being used and is almost always a bad
idea in practical situations.

N - [out]
double array with capacity order*order.
The returned values are:

If "N" were declared as double N[order][order], then

k
N[d-k][i] = N (t) = value of i-th degree k basis function at t.
i
where 0 <= k <= d and k <= i <= d.

In particular, N, ..., N[d] - values of degree d basis functions.
The "lower left" triangle is not initialized.

Actually, the above is true when knot[d-1] <= t < knot[d].  Otherwise, the
value returned is the value of the polynomial that agrees with N_i^k on the
half open domain [ knot[d-1], knot[d] )

If a degree d NURBS has n control points, then the OpenNURBS knot vector
for the entire NURBS curve has length d+n-1. The knot[] paramter to this
function points to the 2*d knots active for the span being evaluated.

Most literature, including DeBoor and The NURBS Book,
duplicate the Opennurbs start and end knot values and have knot vectors
of length d+n+1. The extra two knot values are completely superfluous
when degree >= 1.

Assume C is a B-spline of degree d (order=d+1) with n control vertices
(n>=d+1) and knot[] is its knot vector.  Then

C(t) = Sum( 0 <= i < n, N_{i}(t) * C_{i} )

where N_{i} are the degree d b-spline basis functions and C_{i} are the control
vertices.  The knot[] array length d+n-1 and satisfies

knot <= ... <= knot[d-1] < knot[d]
knot[n-2] < knot[n-1] <= ... <= knot[n+d-2]
knot[i] < knot[d+i] for 0 <= i < n-1
knot[i] <= knot[i+1] for 0 <= i < n+d-2

The domain of C is [ knot[d-1], knot[n-1] ].

The support of N_{i} is [ knot[i-1], knot[i+d] ).

If d-1 <= k < n-1 and knot[k] <= t < knot[k+1], then
N_{i}(t) = 0 if i <= k-d
= 0 if i >= k+2
= B[i-k+d-1] if k-d+1 <= i <= k+1, where B[] is computed by the call
ON_EvaluateNurbsBasis( d+1, knot+k-d+1, t, B );

If 0 <= j < n-d, 0 <= m <= d, knot[j+d-1] <= t < knot[j+d], and B[] is
computed by the call
ON_EvaluateNurbsBasis( d+1, knot+j, t, B ),
then
N_{j+m}(t) = B[m].
*/
ON_DECL
bool ON_EvaluateNurbsBasis(
int order,
const double* knot,
double t,
double* N
);

/*
Description:
Calculate derivatives of B-spline basis functions.
INPUT:
order - [in]
order >= 1
d = degree = order - 1
knot - [in]
array of length 2*d.
Generally, knot <= ... <= knot[d-1] < knot[d] <= ... <= knot[2*d-1].
These are the knots that are active for the span being evaluated.
der_count - [in]
1 <= der_count < order
Number of derivatives.
Note all B-spline basis derivatives with der_coutn >= order are identically zero.

N - [in]
The input value of N[] should be the results of the call
ON_EvaluateNurbsBasis( order, knot, t, N );

N - [out]
If "N" were declared as double N[order][order], then

d
N[d-k][i] = k-th derivative of N (t)
i

where 0 <= k <= d and 0 <= i <= d.

In particular,
N, ..., N[d] - values of degree d basis functions.
N[order], ..., N[order_d] - values of first derivative.
*/
ON_DECL
bool ON_EvaluateNurbsBasisDerivatives(
int order,
const double* knot,
int der_count,
double* N
);``````

Yes, this is what I was looking for…
Many thanks !!