I have constructed a BSplineFunction
through a set of random points:
p = Table[{20 Cos[2 π t], 20 Sin[2 π t]} + RandomReal[{-15, 15}, 2],
{t, 0, 0.9, 0.1}]
f = BSplineFunction[p, SplineClosed -> True];
{{15.7336, -3.557}, {11.1177, -2.53343}, {15.4259, 19.1467}, {6.60292, 10.5131},
{-28.5053, 10.9099}, {-22.7909, -1.35239}, {-3.22756, -13.0483},
{-17.1309, -32.426}, {6.23965, -7.05847}, {25.0532, -25.0634}}
I then drew the spline and 3 curves parallel to it:
Show[ParametricPlot[Table[f[x] + {{0, 1}, {-1, 0}}.Normalize[f'[x]] * i,
{i, 0, 3}], {x, 0, 1}]]
I next wanted to find the length of these curves, but the following command can only find the length of the spline, not the adjacent curves. It gives an error for the other curves.
Table[NIntegrate[Norm[D[f[x] + {{0, 1}, {-1, 0}}.Normalize[f'[x]]*i, x]],
{x, 0, 1}], {i, 0, 3}]
{148.521,(*Unevaluated Expression*),
(*Unevaluated Expression*),(*Unevaluated Expression*)}
Attempting to solve my problem, I found that my difficulty seems to be in getting Mathematica to calculate the derivative first before substituting in values during the integration step. E.g. this does not evaluate to a value:
D[f[x] + {{0, 1}, {-1, 0}}.Normalize[f'[x]], x] /. x -> 0.5
{23.4356 - 4.78553 Norm'[{28.2999, -155.368}],
-134.177 - 3.79751 Norm'[{28.2999, -155.368}]}
If my function was explicit, I know how to fix this, but given that my function isn't explicitly defined, I find my knowledge of Mathematica is lacking to fix this.
For reference if required, I am using version 10.2.
Answer
Combining the results from this answer and this answer, here is how to get the lengths of your parallel curves:
p = {{15.7336, -3.557}, {11.1177, -2.53343}, {15.4259, 19.1467}, {6.60292, 10.5131},
{-28.5053, 10.9099}, {-22.7909, -1.35239}, {-3.22756, -13.0483}, {-17.1309, -32.426},
{6.23965, -7.05847}, {25.0532, -25.0634}};
m = 3; (* degree *) n = Length[p];
fn[t_] = Table[BSplineBasis[{m, ArrayPad[Subdivide[n], m, "Extrapolated"]}, j - 1, t],
{j, n + m}].ArrayPad[p, {{0, m}, {0, 0}}, "Periodic"];
Table[NIntegrate[Sqrt[#.#] &[D[fn[t] - i #/Sqrt[#.#] &[Cross[fn'[t]]], t]], {t, 0, 1}],
{i, 0, 3}]
{148.52091182623133, 154.80408759110168, 161.08726314974254, 167.37043875503448}
Comments
Post a Comment