3
$\begingroup$

I am having trouble implementing an algorithm for 3rd degree NURBS. I have been able to program 2nd degree ones from the equations described here but I am not able to derive an equation for Rational B-Splines of degree 3. The author describes the Rational Knot Equation as NURBS that is a non-recursive form of the De Boor's Algorithm from there I was able to program Rational Internal Control Points: Bn and Cn as:

/* Note that I had to modify the equations to work from the first point on the list as the ones described in the article only took into account points from the second index **Pn+1**. I though that could have been the problem and rewrote them as they where originally written but that did not solve the issue, so I am posting the ones that work from **Pn** */

// Point B. 
/* Iterate over the points(3d vector), knots(double) and weights(double) lists to get the Internal Control Points(3d vector) for the 3rd degree Bézier curves. */

 // Precompute:
double knotE = ( knots[i + 4] - knots[i + 2] ) / ( knots[i + 4] - knots[i + 1] );
double knotEO = ( knots[i + 2] - knots[i + 1] ) / ( knots[i + 4] - knots[i + 1] );

double rationalWeight = (  weights[i] * knotE ) + ( weights[i + 1] * knotEO );
double w1 = weights[i] / rationalWeight;
double w2 = weights[i + 1] / rationalWeight;

/* Our Point3d class lets us multiply a vector by a scalar. */
Point3d b = new Point3d( ( knotE * points[i] * w1 ) + ( knotEO * points[i + 1] * w2 ) );

// Point C. 
/* Iterate over the points, knots and weights lists to get the Internal Control Points for the 3rd degree Bézier curves. */

 // Precompute:
double knotE = ( knots[i + 4] - knots[i + 3] ) / ( knots[i + 4] - knots[i + 1] );
double knotEO = ( knots[i + 3] - knots[i + 1] ) / ( knots[i + 4] - knots[i + 1] );

double rationalWeight = (  weights[i] * knotE ) + ( weights[i + 1] * knotEO );
double w1 = weights[i] / rationalWeight;
double w2 = weights[i + 1] / rationalWeight;

/* Our Point3d class lets us multiply a vector by a scalar. */
Point3d c = new Point3d( ( knotE * points[i] * w1 ) + ( knotEO * points[i + 1] * w2 ) );

But when I apply the same process for point Vn I get results that are not the ones I am looking for:

// Point V. 
/* Iterate over the c, b, knots and weights lists to get the Internal Control Points for the 3rd degree Bézier curves. */

 // Precompute:
double knotE = ( knots[i + 4] - knots[i + 3] ) / ( knots[i + 4] - knots[i + 2] );
double knotEO = ( knots[i + 3] - knots[i + 2] ) / ( knots[i + 4] - knots[i + 2] );

double rationalWeight = (  weights[i] * knotE ) + ( weights[i + 1] * knotEO );
double w1 = weights[i] / rationalWeight;
double w2 = weights[i + 1] / rationalWeight;

/* Our Point3d class lets us multiply a vector by a scalar. */
Point3d v = new Point3d( ( knotE * c[i] * w1 ) + ( knotEO * b[i + 1] * w2 ) );

When all the weights are the same the points respond as expected, when the weights are not the same points Bn and Cn work as they should but Vn responds incorrectly. So my Vn Equation must be wrong. As the function inputs Bn and Cn lists of points my guess is that I am missing a relationship between those two equations with the one I am having trouble with.

As my problem is with the mathematical concept instead of an inplementation this is considered a language agnostic question.

Here's a picture of a 3d degree UniformBSpline UBS which I programmed succesfully already but that may help if the link to the resource goes down.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.