Interpolation of a NURBS curve

Known that NQ=P where N is the Bspline basis function, Q is the control point that we wish to locate, P is the data points given ( the curve must pass through it) is there any way to modify the "N" such that it is rationalized with desired weight so that we can interpolate a NURBS curve through it?

I've tried to modify the Basis function matrix and tried to Rationalize it by adding weight and dividing. The result is the curve didn't pass through data points.

• I don't see why this question is specific to the software Mathematica. I vote to move this to http://scicomp.stackexchange.com/. – halirutan Feb 10 '15 at 7:46
• My apologies, I've edited the question. It originally is related with mathematica. I just didn't upload my code. – Keith Lim Feb 10 '15 at 7:56
• You should post your actual code, not images. You can go to the help centre and read more about proper code formatting – Sektor Feb 10 '15 at 9:57

The procedure for doing a weighted B-spline interpolation is not too different from the unweighted case. I'll use the same point set in the docs, and add a weight vector that gives higher weight to the second and fifth points:

pts = {{1., 2.}, {0., 1.}, {2., 0.}, {2., 2.}, {3., 3.}, {5., 2.}};
wts = {1, 4, 1, 1, 4, 1};


Here again is Lee's algorithm, which I'll use this time to perform chord-length parametrization:

parametrizeCurve[pts_ /; MatrixQ[pts, NumericQ], a : (_?NumericQ) : 1/2] :=
FoldList[Plus, 0, Normalize[(Norm /@ Differences[pts])^a, Total]];
tvals = parametrizeCurve[pts, 1];


Set up the knots for a cubic NURBS, and the basis function matrix:

m = 3;
knots = Join[ConstantArray[0, m + 1], MovingAverage[ArrayPad[tvals, -1], m],
ConstantArray[1, m + 1]];
bas = Table[BSplineBasis[{m, knots}, j - 1, tvals[[i]]],
{i, Length[pts]}, {j, Length[pts]}];


Up to this point, the proceedings have been exactly the same as with the unweighted case. For comparison purposes, let's generate the unweighted control points:

cn = LinearSolve[bas, pts];


Now, spot the differences between the previous snippet and the following snippet for the weighted control points:

cw = LinearSolve[bas, bas.wts pts]/wts;


Now, let's show the points along with the unweighted (red) curve and the weighted (blue) curve:

Graphics[{{Red, BSplineCurve[cn, SplineDegree -> m, SplineKnots -> knots]},
{Blue, BSplineCurve[cw, SplineDegree -> m, SplineKnots -> knots,
SplineWeights -> wts]},
{Green, AbsolutePointSize[6], Point[pts]}},
PlotRange -> {{-1, 6}, {-1, 13/4}}]


Note the sharper turns in the blue curve. You should now be able to see why weighted interpolations are in fact not that commonly done.

• Dear J.M. I would like to ask you a question. For the built-in BSplineBasis, what is the default knots in the BSplineBasis[d,n,x]? For instance, By the result of BSplineBasis[3,1,x] // PiecewiseExpand, I guess the default knots is knots ={1/4,1/4,1/4,1/4,2/4,3/4,4/4,5/4,5/4,5/4,5/4}. However, when I execute the code BSplineBasis[{3,knots}},1,x] // PiecewiseExpand, which gives a different result from BSplineBasis[3,1,x] // PiecewiseExpand .Namely, my guess is wrong. THX. – xyz Jul 29 '15 at 8:20
• @Shutao, clamped uniform knots over $[0,1]$ are used by default, if memory serves. – J. M. will be back soon Jul 29 '15 at 8:37
• According @J. M. to your description, is it the defaut knots={0,0,0,0,1/4,2/4,3/4,1,1,1,1}? But the result of BSplineBasis[3,1,x] // PiecewiseExpand is different from BSplineBasis[{3,knots}},1,x] // PiecewiseExpand. Maybe I have a wrong understanding:-) – xyz Jul 29 '15 at 9:19
• I do not have access to a computer right now to check. Let me get back to you when I can do so. – J. M. will be back soon Jul 29 '15 at 9:46
• OK, @J. M.　THX a lot　:) – xyz Jul 29 '15 at 10:01