3
$\begingroup$

I would like to use MeshFunctions in ParametricPlot in combination with BSplineFunction to extract parameters for points on the curve.

I have a set of points:

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

Then I use BSplineFunction to create a BSpline curve. BSplineFunction[...]][u] gives the point on a B-spline curve corresponding to parameter u.

I want to find the parameter u corresponding to a point on the curve. For that I can use FindRoot:

u = 
  Table[
    u /. FindRoot[function[u][[1]] == pts[[i, 1]], {u, 0.0, 1.0}], 
    {i, Length[pts - 1]}
  ]

I would like to use MeshFunctions for this. How can I do that?

$\endgroup$
4
  • $\begingroup$ What is the definition of function in your code? What advantage do you seek from MeshFunctions that is not achievable with the solution you have now? $\endgroup$
    – MarcoB
    Commented Sep 29, 2022 at 14:32
  • $\begingroup$ The pts is control points, does not on the curve. BTW, function[u][[1]] is {0., 3., -1., -4., -4.}, so the FindRoot does not take effect. $\endgroup$
    – cvgmt
    Commented Sep 29, 2022 at 14:49
  • $\begingroup$ Hi MarcoB, FindRoot doesn't find all solutions, especially if for one parameter u two points exist on the y-axis. Using MeshFunctions give me the points. How to obtain from these points the parameter u. I would really appreciate this. $\endgroup$
    – Kerry
    Commented Sep 29, 2022 at 14:53
  • $\begingroup$ Hi cvgmt, There is a misunderstanding, sorry. I don't need the control points. I would like to get from a arbitrary point {x[u], y[u]} on the curve the corresponding parameter u. $\endgroup$
    – Kerry
    Commented Sep 29, 2022 at 14:59

2 Answers 2

3
$\begingroup$

The effect maybe like this.

Clear[pts, f, reg];
pts = {{0, 0}, {3, 4}, {-1, 4}, {-4, 0}, {-4, -3}};
f = BSplineFunction[pts];
reg = ParametricRegion[{Indexed[f@u, 1], 
     Indexed[f@u, 2]}, {{u, 0, 1}}] // DiscretizeRegion;
Manipulate[Module[{sol, u, q},
  sol = NMinimize[{EuclideanDistance[{Indexed[f@u, 1], 
        Indexed[f@u, 2]}, pt], 0 <= u <= 1}, u][[2]];
  q = f@u /. sol;
  ParametricPlot[f@u, {u, 0, 1}, 
   Epilog -> {Text[Style["u=" <> ToString[u /. sol], Red, 14], 
      q, {0, -2}]}, PlotRange -> 5]], {{pt, [email protected]}, Locator, 
  TrackingFunction -> (pt = RegionNearest[reg]@#; &)}]

enter image description here

$\endgroup$
1
  • $\begingroup$ Dear cvgmt. This is great. Thank you very very much. I'm really grateful. $\endgroup$
    – Kerry
    Commented Sep 29, 2022 at 15:46
2
$\begingroup$

We may create a table of {BSpline,u} and then fit a function to it. This function will then return "u" from a data pair {x,y}:

With the BSpline:

pts = {{0, 0}, {3, 4}, {-1, 4}, {-4, 0}, {-4, -3}};
crv[u_] = BSplineFunction[pts][u]

we create the table:

dat = Table[{crv[u], u}, {u, 0, 1, 0.01}];

then we define our function:

fun[{x_, y_}] = Interpolation[dat, InterpolationOrder -> 1][x, y]

To test, we may write:

fun[crv[0.4]] == 0.4

(* True *)
$\endgroup$
1
  • $\begingroup$ Hi Daniel, thank you very much. This is also a nice solution. Thanks. $\endgroup$
    – Kerry
    Commented Sep 29, 2022 at 16:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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