IN THIS CODE:
1. Calculate basis functions and store values
2. Use stored values to calculate a curve
3. Draw the curve
.h File
.cpp File
Periodic Knot Vector
<--------------------
Open Knot Vector
<--------------------
Bezier Equivalent
<--------------------
void BSpline :: draw(){
glColor3f(1,1,1);
glBegin(GL_LINE_STRIP);
for (int i = 0; i <= mRes; ++ i) {
//calculateBasis(i);
Vector3f v = valueAt(i);
glVertex3f(v.x,v.y,v.z);
}
glEnd();
if (bDrawHull) drawHull();
drawBasisGraph();
}
Vector3f BSpline :: valueAt(int step){
Vector3f v_out;
for (int i = 0; i < mNumPoints; ++i){
Vector3f v_temp = mControlPoints[i];
v_temp *= mBasisGraph[i * mRes + step];
v_out += v_temp;
}
return v_out;
}
void BSpline :: calculateBasis (int step){
float p = (mTMax / mRes);
float t = step * p;
float a[mNumPoints];
float b[mNumPoints];
float N[mNumKnots];
/* For Each Control Point Order 1 */
for (int i = 0; i < mNumKnots - 1; ++ i) {
float N1;
/* Check Value of N at 1st Order of K to make
sure we are only evaluating N for the two
control points that surround it
*/
if ( ( t >= mKnotVector[i] ) && ( t < mKnotVector[i+1] ) ) {
N1 = 1;
} else {
N1 = 0;
}
N[i] = N1;
}
/* NEXT: DIVIDED DIFFERENCES ARE THE MAIN ELEMENTS OF THE BSPLINE EQUATION */
/*
For the each increasing Order of K, we must Store an array
of "Values of Influence". Each element of this array will be
referenced by the NEXT HIGHER Order calculations.
These values are namely the ratios of differences between the current
t and various knot values at i and i + k - 1, and i + 1 and i + k etc.
*/
/* For Each Increasing Order up to Order K */
for (int k = 2; k < mOrderK + 1; ++ k){
/*
Iterate Through Knot Vectors And Store Its Influence On Control Point i
*/
for (int i = 0; i < mNumKnots - k; ++ i) {
float a1 = t - mKnotVector[i]; //subtract knot value from current time
float a2 = mKnotVector[i + k - 1] - mKnotVector[i]; //subtract this knot value at i from the one K values down
float b1 = mKnotVector[i + k] - t; //subtract time value from knot value K values down
float b2 = mKnotVector[i + k] - mKnotVector[i + 1]; //subtract next knot from K + 1 knot
//Store Ratios Into Array, of the Surround Control Points A and B:
//CHECK for divide by zero to avoid NAN errors in nonuniform B-splines
a2 == 0 ? a[i] = 0 : a[i] = ( N[i] ) * a1 / a2;
b2 == 0 ? b[i] = 0 : b[i] = ( N[i+1] ) * b1 / b2;
N[i] = a[i] + b[i];
}
}
/*
We should now have a specifc amount of input
for each Control Point at time t. We want to
return an x and y value still! Lets
plot these Values' Basis Functions.
And return a point that is a sum of the
basis functions of all the Control Points at time t
*/
for (int i = 0; i < mNumPoints; ++i){
mBasisGraph[i * mRes + step] = N[i];
}
}