<p>I am having trouble implementing an algorithm for 3rd degree NURBS.
I have been able to program 2nd degree ones from the equations described <a href="https://www.codeproject.com/Articles/996281/NURBS-curve-made-easy" rel="nofollow noreferrer" title="equations">here</a> but I am not able to derive an equation for Rational B-Splines of degree 3. The author describes the Rational Knot Equation as <a href="https://i.sstatic.net/kmIJK.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/kmIJK.jpg" alt="NURBS"></a> that is a non-recursive form of the <a href="https://en.m.wikipedia.org/wiki/De_Boor%27s_algorithm" rel="nofollow noreferrer">De Boor's Algorithm</a> from there I was able to program <strong>Rational Internal Control Points: Bn</strong> and <strong>Cn</strong> as:</p>

<pre><code>/* 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 ) );
</code></pre>

<p>But when I apply the same process for point <strong>Vn</strong> I get results that are not the ones I am looking for:</p>

<pre><code>// 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 ) );
</code></pre>

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

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

<p>Here's a picture of a 3d degree UniformBSpline <a href="https://i.sstatic.net/29xeO.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/29xeO.jpg" alt="UBS"></a> which I programmed succesfully already but that may help if the link to the resource goes down.</p>

CC BY-SA 4.0
2020-12-12T01:50:16.127Z
This is old, I have an implementation in that generates them in the arbitrary degree, so that might make it easier to figure out for the 3 degree case:

https://gitlab.com/Makogan/mathproofs/-/blob/master/B-splines/b-splines.pdf

Scroll down and towards teh end there is python code that calculates a B-Spline for arbtirary degree
Makogan
CC BY-SA 4.0
2020-12-13T23:25:55.160Z
@Makogan you mean generating arbitrary degree Bézier curves from a NURBS?
Felipe Gutierrez
CC BY-SA 4.0
2020-12-13T23:38:01.173Z
No, I mean that NURBS have a degree, which is the maximum number of derivatives you can take before the derivatives become discontinous.

Bezier curves are NURBS but not all NURBS are bezier curves. The most important distinction is that Bexeir curves have global support whereas NURBS have local support.
Makogan
CC BY-SA 4.0
2020-12-13T23:39:41.800Z
i.e. NURBS can be described generically and for arbitrary degree and you just pass the degree as a parameter when doing your computations. So instead of implementing it for a specific case, you can implement nurbs for any arbitrary degree and be done.
Makogan
CC BY-SA 4.0
2020-12-14T21:09:55.593Z
@Makogan yes I am aware of that and I have code that does that for arbitrary degrees too, but this is related to generating poly-Bézier curves that match a NURBS. Thanks anyway though.
Felipe Gutierrez
<mathematics><computational-geometry><linear-algebra>
NURBS Weights De Boor's Algorithm
Felipe Gutierrez
# NURBS Weights De Boor's Algorithm

(Asked by: username_0 on 2019-04-06)

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](https://www.codeproject.com/Articles/996281/NURBS-curve-made-easy "equations") 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](https://i.sstatic.net/kmIJK.jpg)](https://i.sstatic.net/kmIJK.jpg) that is a non-recursive form of the [De Boor's Algorithm](https://en.m.wikipedia.org/wiki/De_Boor%27s_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](https://i.sstatic.net/29xeO.jpg)](https://i.sstatic.net/29xeO.jpg) which I programmed succesfully already but that may help if the link to the resource goes down.

**Tags:** mathematics, computational-geometry, linear-algebra

> **Comments:**
> **username_1**: This is old, I have an implementation in that generates them in the arbitrary degree, so that might make it easier to figure out for the 3 degree case:  https://gitlab.com/username_1/mathproofs/-/blob/master/B-splines/b-splines.pdf  Scroll down and towards teh end there is python code that calculates a B-Spline for arbtirary degree  
> **username_0**: @username_1 you mean generating arbitrary degree Bézier curves from a NURBS?  
> **username_1**: No, I mean that NURBS have a degree, which is the maximum number of derivatives you can take before the derivatives become discontinous.  Bezier curves are NURBS but not all NURBS are bezier curves. The most important distinction is that Bexeir curves have global support whereas NURBS have local support.  
> **username_1**: i.e. NURBS can be described generically and for arbitrary degree and you just pass the degree as a parameter when doing your computations. So instead of implementing it for a specific case, you can implement nurbs for any arbitrary degree and be done.  
> **username_0**: @username_1 yes I am aware of that and I have code that does that for arbitrary degrees too, but this is related to generating poly-Bézier curves that match a NURBS. Thanks anyway though.  

---

## 0 answers

