3
$\begingroup$

Last month, I answered a question about spline interpolation,please see here

Now I do the following operations

pts=
  {{0, 0.}, {3, 4}, {-1, 5}, {-4, 0}, {-5, -3}, {-10, -11}, {-11, -12}}
xy = Interpolation[pts, Method -> "Spline", InterpolationOrder -> 4];

graph1=
  Plot[xy[t], {t, Min[pts[[All,1]]], Max[pts[[All,1]]]}, 
    Epilog -> {PointSize[Medium], Point[pts]}, 
    AspectRatio -> Automatic, ImageSize -> 300, PlotRange -> {{-10, 10}, {-15, 10}}]

enter image description here

However, when I used my function visualizeBSpline, it given a different result.

graph2 = visualizeBSpline[pts, 4, ImageSize -> 300]

enter image description here

Show[{graph1,graph2}]

enter image description here

Question

  • Why the result of Interpolation[pts, Method -> "Spline"] is different from BSplineCurve.
  • How to make the result of Interpolation[pts, Method -> "Spline"] and BSplineCurve same.

Edit

Thanks for march's hint

graph3 =
  visualizeBSpline[Sort[pts], 4, ImageSize -> 300, PlotRange -> {{-10, 10}, {-15, 16}}]

enter image description here

When I sort the pts, the results of Interpolation and BSplineCurve are still different.

Show[{graph3, graph1}]

enter image description here

$\endgroup$
  • 1
    $\begingroup$ What do you get if you do instead visualizeBSpline[Sort[pts], 4, ImageSize -> 300]? $\endgroup$ – march Jul 13 '15 at 3:13
  • 2
    $\begingroup$ A interpolation function must represent a single-vaued function of one variable. A BSpline is not a function but the parametric representation of a curve. Why do you think their plotted trace should look the same? $\endgroup$ – m_goldberg Jul 13 '15 at 3:26
  • $\begingroup$ @m_goldberg, At first, When I know the Interpolation has the Method->Spline, I think they use the same theory The NURBS, so I simply think their result should be same . $\endgroup$ – xyz Jul 13 '15 at 3:35
  • $\begingroup$ @march, Thanks for your hint. BTW, is it possible to let the Interpolation unsort the pts. $\endgroup$ – xyz Jul 13 '15 at 3:37
  • $\begingroup$ You've seen this? $\endgroup$ – J. M. will be back soon Jul 13 '15 at 3:37
3
$\begingroup$

As m_goldberg said in the comment

A interpolation function must represent a single-vaued function of one variable. A BSpline is not a function but the parametric representation of a curve

To achieve the same interpolation result, I must interpolate the data in two directions.

The interpolateCurve function gives the interpolation of curves.

enter image description here

Options[interpolateCurve] = 
  Join[Options[ParametricPlot3D], Options[Interpolation]];

interpolateCurve[pts : {{_, _} ..}, opts : OptionsPattern[]] :=
  Module[{order, x, y, s, func1, func2},
    order = OptionValue[InterpolationOrder];
    x = pts[[All, 1]];
    y = pts[[All, 2]];
    (*calculate the accumulative chord length*)
    s =
     FoldList[
       Plus, 0, EuclideanDistance @@@ Partition[pts, 2, 1]];
    (*interpolation points with spline-method in two directions*)
    {func1, func2} =
      Interpolation[
       Thread@{s, #}, InterpolationOrder -> order, Method -> "Spline"] & /@ {x, y};
    (*visualize the curve*)
    ParametricPlot[{func1[t], func2[t]}, {t, 0, Last[s]},
     Evaluate@
      (Sequence @@ FilterRules[{opts}, Options[ParametricPlot]]), 
     Epilog -> {Red, PointSize[Medium], Point[pts]}]
  ]

Test

curvepoints = {{0, 0.}, {3, 4}, {-1, 5}, {-4, 0}, {-4, -3}, {-10, -11}, {-11, -12}};

{interpolateCurve[curvepoints, InterpolationOrder -> 3, 
  ImageSize -> 300, PlotRange -> {{-10, 10}, {-15, 10}}],
 visualizeBSpline[curvepoints, 3, ImageSize -> 300]}

enter image description here

Show[%]

enter image description here

pts={{0, 0.}, {3, 4}, {-1, 5}, {-4, 0}, {-5, -3}, {-10, -11}, {-11, -12}};

{interpolateCurve[pts, InterpolationOrder -> 3, ImageSize -> 260, 
  PlotRange -> {{-10, 10}, {-15, 10}}],
visualizeBSpline[pts, 3, ImageSize -> 260]}

enter image description here

$\endgroup$
3
+25
$\begingroup$

My answer here is effectively an answer to this question as well; I'll leave to other people the decision of whether to close this as a dupe. Details on the proceedings can be read in my other answer. Here, I will merely present results:

pts = SortBy[{{0., 0.}, {3., 4.}, {-1., 5.}, {-4., 0.}, {-5., -3.},
              {-10., -11.}, {-11., -12.}}, First];

m = 4; n = Length[pts];
{xa, ya} = Transpose[pts];
knots = Join[ConstantArray[xa[[1]], m + 1], 
             If[m + 2 <= n, MovingAverage[ArrayPad[xa, -1], m], {}], 
             ConstantArray[xa[[-1]], m + 1]];
cp = LinearSolve[Outer[BSplineBasis[{m, knots}, #2, #1] &, xa,
                       Range[0, Length[pts] - 1]], ya];

if = Interpolation[pts, InterpolationOrder -> m, Method -> "Spline"];
sf = BSplineFunction[List /@ cp, SplineDegree -> m, SplineKnots -> knots];

Plot[{if[x], sf[x]}, {x, -11, 3}, Axes -> None, 
     Epilog -> {Directive[AbsolutePointSize[8], RGBColor[7/19, 37/73, 22/31]],
                Point[pts]}, Frame -> True, 
     PlotStyle -> {Directive[AbsoluteThickness[5], RGBColor[7/19, 37/73, 22/31]], 
                   Directive[AbsoluteThickness[2], RGBColor[59/67, 11/18, 1/7]]}]

two splines

Plot[if[x] - sf[x], {x, -11, 3}, Axes -> None, Frame -> True, 
     PlotRange -> All, PlotStyle -> RGBColor[7/19, 37/73, 22/31]]

they look the same, don't they?

$\endgroup$

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