Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Is there a way to decompose a BSplineFunction output into two functions x[t], y[t] parametrizing the curve BSplineFunction[{{x1, y1}, {x2, y2}, ...}][t] in a form which allows easy calculation of derivatives of arbitrary order of x[t] and y[t] and of composite functions which use x[t] or y[t] like

f[t] = y''[t]/Sqrt[x'[t]^2+y'[t]^2]
f''[0.5]

etc. ?

Edit: I would also like to do this avoiding SetDelayed as much as it's possible.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

When manipulating B-splines in this manner, it is often convenient to fall back on the definitions. Luckily, since Mathematica supplies the function BSplineBasis[], using the definitions are easy:

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

n = 3; (* B-spline degree *)
m = Length[pts];
(* clamped uniform knots for B-spline *)
knots = {ConstantArray[0, n + 1], Range[m - n - 1]/(m - n), ConstantArray[1, n + 1]}
        // Flatten;

{xu, yu} = Transpose[pts];
bs = BSplineFunction[pts, SplineDegree -> n];

(* B-spline component functions *)
f[t_] = xu.Table[BSplineBasis[{n, knots}, i - 1, t], {i, Length[pts]}];
g[t_] = yu.Table[BSplineBasis[{n, knots}, i - 1, t], {i, Length[pts]}];

Compare:

{ParametricPlot[bs[t], {t, 0, 1}, Axes -> None, Frame -> True,
                Epilog -> {Directive[AbsolutePointSize[5], Red], Point[pts]}], 
 ParametricPlot[{f[t], g[t]}, {t, 0, 1}, Axes -> None, Frame -> True,
                Epilog -> {Directive[AbsolutePointSize[5], Red], Point[pts]}]}

Spot the difference!

One can now plot the component functions as needed:

Plot[{f[t], g[t]}, {t, 0, 1}, Axes -> None, Frame -> True]

B-spline components

or use derivatives:

With[{t = 1/3}, g''[t]/Sqrt[f'[t]^2 + g'[t]^2]]
   48/Sqrt[41]
share|improve this answer
    
This is great, thank you so much! –  level1807 Oct 27 '13 at 16:39

What about trying something like the following!

pts = {{1, 1}, {2, 3}, {3, -1}, {4, 1}, {5, 0}};
f = BSplineFunction[pts];
x[t_?NumericQ] := Module[{val}, val = f[t]; First@val];
y[t_?NumericQ] := Module[{val}, val = f[t]; Last@val];

Check it!

Plot[{x[t], y[t]}, {t, 0, 1}, Frame -> True]

enter image description here

Now the value you are looking for.

nf[t_?NumericQ] := y''[t]/Sqrt[x'[t]^2 + y'[t]^2];
nf''[0.5]

-758.244

BR

share|improve this answer
    
Wow, that's a simple and awesome idea! SetDelayed did half of the job, but Module is obviously the winner. Thanks! –  level1807 Feb 7 '13 at 14:07
    
Though is there a way to do this without SetDelayed? I intend to use these functions in NDSolve inside Manipulate, thus SetDelayed is not welcome. x[t] by its nature is a known value, so why does it need to be SetDelayed? –  level1807 Feb 7 '13 at 14:18

Your Answer

 
discard

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.