Hello
I have a problem calculating the basis functions for knot vectors that
are not clamped.
I use the algorithm from the Piegl/Tiller NURBS book (ALGORITHM A2.2, page 70)
Piegl/Tiller always assume that the knot vector is clamped, i.e. knot values
are of multiplicity order (degree + 1) at the start and the end.
Unfortunately the data I have to deal with doesn't always looks like that,
e.g. I have a knot vector for a curve of degree 3 that begins like:
-7.62939453147204E-06,-7.62939453147204E-06,0.0,0.0,0.00390624999999359 ...
and even ends with:
1.,1.,1.00390624999999,1.00781249999999
i.e. multiplities look like:
2,2,1...2,1,1 instead of 4,1...1,4
I already changed the algorithm to find the span for a parameter u to return
the real span [1..m-1] instead of Piegl/Tillers version that returns only spans
between [p..m-p].
But now I have problems (I think) getting the basis functions and evaluating the
curve. My methods GetBasisFunctions (what implements Piegl/Tillers BasisFuns)
and Evaluate (what implements Piegl/Tillers CurvePoint) look like follows:
DoubleVector
B_Spline_Curve::GetBasisFunctions(double u) const
{
DoubleVector U = GetKnotVector();
const int i = FindSpan(u);
DoubleVector N(m_degree + 1);
unsigned int p = m_degree;
N[0] = 1.;
DoubleVector left(p + 1);
DoubleVector right(p + 1);
for (unsigned int j = 1; j <= p; ++j) {
left[j] = u - U[i + 1 - j];
right[j] = U[i + j] - u;
double saved = 0.;
for (unsigned int r = 0; r < j; ++r) {
double temp = N[r] / (right[r + 1] + left[j - r]);
N[r] = saved + right[r + 1] * temp;
saved = left[j - r] * temp;
}
N[j] = saved;
}
return N;
}
Cartesian_Point*
B_Spline_Curve::Evaluate(ParameterValue value) const
{
Cartesian_Point* result = NULL;
int span = FindSpan(value);
DoubleVector knotvector = GetKnotVector();
int ksize = knotvector.size();
assert(span > 0 && span < ksize);
if ((span > 0) && (span < (ksize))) {
result = new Cartesian_Point(0., 0., 0.);
DoubleVector basisfunction = GetBasisFunctions(value);
int ctrlpoint_index = 0;
int ctrlpoint_count = m_control_points_list.size();
for (unsigned int i = 0; i <= m_degree; ++i) {
ctrlpoint_index = span - m_degree + i;
if (ctrlpoint_index >= 0 && ctrlpoint_index < ctrlpoint_count - 1) {
Cartesian_Point* pnt = m_control_points_list[ctrlpoint_index];
Cartesian_Point* epnt = basisfunction[i] * *pnt;
Cartesian_Point* old = result;
result = *old + *epnt;
}
}
}
return result;
}
Can somebody enlighten me here?
Thanks in advance
Thomas
--
Dr. Thomas Krebs
Zuken Ltd.
Roonstr. 21
90429 Nrnberg
Germany
Tel.: ++49 911 9269 111
Fax.: ++49 911 9269 200