Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Old package, works good


testData = 
  {{10, 10}, {10, 20}, {10, 25}, {10, 27}, {10, 28}, {9, 26}, {8, 25}, {5, 20}, {3, 1}};

fFit = SplineFit[testData, Cubic];

ParametricPlot[fFit[n], {n, 0, Length[testData] - 1}, Epilog -> Point[testData]]

New spline package, how to make it work like the old one: passing each point exactly and naturally smooth

fFit01 = BSplineFunction[testData];

ParametricPlot[fFit01[n], {n, 0, Length[testData] - 1}, 
               Epilog -> Point[testData]]

However,the fitting results are different: some points are not passed exactly, which is not what I need.

share|improve this question

I've used the method I'm about to show in this answer, but I suppose having it explicitly answer an interpolation question would be convenient.

Starting with your points,

testData = {{10, 10}, {10, 20}, {10, 25}, {10, 27}, {10, 28}, {9, 26},
            {8, 25}, {5, 20}, {3, 1}};

we use Lee's centripetal parametrization scheme to generate corresponding parameter values:

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

tvals = parametrizeCurve[testData];

We then generate control points for the B-spline from the interpolation points. To do that, we use a procedure suggested by Piegl and Tiller (see The NURBS Book by Piegl and Tiller if you want more details):

m = 3; (* degree of the B-spline *)
(* knots for interpolating B-spline *)
knots = Join[ConstantArray[0, m + 1], MovingAverage[ArrayPad[tvals, -1], m],
             ConstantArray[1, m + 1]];
(* basis function matrix *)
bas = Table[BSplineBasis[{m, knots}, j - 1, tvals[[i]]] // N,
            {i, Length[testData]}, {j, Length[testData]}];
ctrlpts = LinearSolve[bas, testData];

Now, we can see the B-spline in two different ways:

{Graphics[{{ColorData[1, 1], BSplineCurve[ctrlpts, SplineDegree -> m,
                                          SplineKnots -> knots]},
           {Directive[Green, AbsolutePointSize[6]], Point[testData]}}, Frame -> True], 
 ParametricPlot[BSplineFunction[ctrlpts, SplineDegree -> m, SplineKnots -> knots][t]
                // Evaluate, {t, 0, 1}, Axes -> None,
                Epilog -> {Directive[Green, AbsolutePointSize[6]], Point[testData]},
                Frame -> True]} // GraphicsRow

B-spline in two different ways

It can be observed that parametrizeCurve[] takes a second argument; this controls the type of parametrization used for the points. The default setting of $1/2$ generates a centripetal parametrization, as previously mentioned. Setting that parameter to $1$ will yield a chord-length parametrization, and setting it to $0$ yields a uniform parametrization. This parameter can take values in $[0,1]$, and one can adjust it as needed for the application at hand.

share|improve this answer
Sorry for mis-state my problem, thanks a lot. – yanfyon Jun 12 '13 at 17:19

The data points you provided to BSplineFunction act as spline control points. Generally, splines do not go through them. The effect you want to achieve can be gotten using Interpolation:

First plotting your function with a prettier aspect ratio:

    {n, 0, Length[testData] - 1}, 
    Epilog -> Point[testData], AspectRatio -> 1/GoldenRatio]

enter image description here

fFit01 = Interpolation[{Range[Length@testData], testData}\[Transpose], Method -> "Spline"];

  Table[fFit01[n], {n, 1, Length[testData], 0.01}], 
  Epilog -> Point[testData], Joined -> True


There are some small differences in the beginning of the curve that can be reduced by specifying derivatives at that point or by lowering the InterpolationOrder option in Interpolate. enter image description here

share|improve this answer
Great, thanks a lot!!!! – yanfyon Jun 12 '13 at 17:18

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.