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.

Once again a big thank you for the great help in my earlier post: Plotting function with Dynamic parameter. It totally worked out.

I now have a new coding problem

Manipulate[
  Plot[Norm @ p2*t + Norm @ p1, {t, 0, 1}, PlotRange -> {0, 5}], 
  {{p1, {0, 0}}, Locator}, 
  {{p2, {0, 0}}, Locator}]

Given this Manipulate object, how would it be possible to add a new locator that has its movement constrained to a given parametric curve? I've tried the code given on the user manual of Locator and of LocatorPane, but without success.

share|improve this question
    
What's the parametric curve you are talkig about, is it this line? Do you want there 3rd locator? Isn't LocatorPane > Applications > 2nd example helpful? –  Kuba Aug 5 '13 at 21:39
    
Thanks for the fast responses: I don't know how to incorporate the answers of the link of m_goldberg and how to incorporate it in the Manipulate object. The parametric curve will be a line, but different from the line trough p1 and p2 in the code above: in general in will be a parametric curve func[t]. Any suggestions? Thank you a lot in advance! –  Gabriel Aug 5 '13 at 21:54
    
By parametric you mean general {x[t], y[t]} or special case {t, y[t]}? –  Kuba Aug 5 '13 at 22:26
    
General {x[t],y[t]}. Is that possible ? –  Gabriel Aug 5 '13 at 23:07
    
I disagree that this is a duplicate. In a very general sense both questions have two answers in the documentation, in Locator > Scope > Locator Control and LocatorPane > Applications and could be considered off-topic. But each has complications that distinguish them from these answers and from each other. Ditto for this related question. –  Michael E2 Aug 6 '13 at 10:33

2 Answers 2

up vote 4 down vote accepted

Maybe this will help. I can adapt my answer here, using the second argument of Dynamic to set the position of the Locator to a point on a parametric curve. We can use FindMinimum to find the point on the parametric curve that is closest to the mouse. To speed things up, it helps to have good initial points for FindMinimium. To do that, we save the values of the parameter t calculated by ParametricPlot in the list t0. Then Nearest is used to find the parameter t of the point of those calculated by ParametricPlot that is closest to the mouse. This t is used as the initial value for FindMinimum. There are alternatives to using the points computed by ParametricPlot (see below). To further speed things up, it can help to reduce the accuracy demanded of FindMinimum. All this requires extra local variables (with no controls, specified by None).

I put Dynamic around LocatorPane so that the initialization code (for plot, nf) would not be reevaluated, except, technically, on the first update after initial evaluation. (This extra evaluation could be eliminated by adding the Manipulate option TrackedSymbols :> {p}.)

f[t_] := t {Cos[10 t], Sin[10 t]};
Manipulate[
 {plot, {t0}} = Reap @ ParametricPlot[f[t], {t, 0, 2}, EvaluationMonitor :> Sow[t]];
 nf = Nearest[f /@ t0 -> t0];
 Dynamic @ LocatorPane[
  Dynamic[
   p,
   (p = f @ Clip[t /. Last @ FindMinimum[EuclideanDistance[f[t], #], {t, First @ nf[#]},
                       AccuracyGoal -> 5, PrecisionGoal -> 4],
                 {0, 2}]) &],
  plot],
 {{p, {0, 0}}, None}, {plot, None}, {t0, None}, {nf, None}
 ]

Mathematica graphics

Alternative initial points

The easiest way is just to take equally spaced values of t:

nf = Nearest[f /@ # -> #] &@ Range[0, 2, 0.01];  (* {0, 2} is the domain of t *)

One advantage to ParametricPlot is that it tends to calculate more points where the curvature is great. Where the curvature is great, FindMinimum sometimes jumps around in its solutions. In our example case, the curvature is greatest near the origin; once the number of values of t is above about 150 or so, the behavior seems smooth. By comparison, ParametricPlot calculates 1645 points, so in some sense this method could be considered optimal in this example case.

A second method is to take point equally spaced along the curve. This can be useful when the velocity of parametrization varies widely. However, where the curvature is tight, the same problem of FindMinimum jumping from one part of the curve to another can occur.

arclength = NDSolveValue[{t'[s] Norm[f'[t[s]]] == 1, t[0] == 0}, 
  t, {s, 0, NIntegrate[Norm[f'[t]], {t, 0, 2}]}]; (* {0, 2} is the domain of t *)
nf = Nearest[f /@ # -> #] &@ 
  (arclength /@ Range @@ Flatten[{#, Differences /@ # / 200}] &@ arclength["Domain"]);
share|improve this answer

If you want to constrain a locator to a line, and want the line itself to be adjustable with endpoint locators, then here is a method. The following routine projects an off-the-line locator perpendicularly onto the line. I generated the somewhat complicated looking result using John Browne's Grassmann algebra application.

ConstrainedLocatorToLine::usage = 
  "ConstrainedLocatorToLine[locator, ptA, ptB] will return new \
locator coordinates that have been projected onto the line defined by \
ptA and ptB. All quantities are in the form of list coordinates: {x, \
y}.";
SyntaxInformation[
   ConstrainedLocatorToLine] = {"ArgumentsPattern" -> {_, _, _}};
ConstrainedLocatorToLine[{xloc_, yloc_}, {xA_, yA_}, {xB_, yB_}] :=
  {xA - ((xA - xB) (xA^2 + xB xloc - 
       xA (xB + xloc) + (yA - yB) (yA - yloc)))/((xA - xB)^2 + (yA - 
       yB)^2), ((xA - xB) (-xB yA + xloc (yA - yB) + xA yB) + (yA - 
       yB)^2 yloc)/((xA - xB)^2 + (yA - yB)^2)};

The following is a DynamicModule illustrating its use with the ever handy second argument of Dynamic.

DynamicModule[
 {ptA = {-1, -1}, ptB = {1, 1}, locator = {0, 0}, constrain},
 constrain[loc_, pa_, 
   pb_] := (locator = ConstrainedLocatorToLine[loc, pa, pb]);
 Graphics[{
   Dynamic@{Line[{ptA, ptB}]},
   Locator[Dynamic[ptA, (ptA = #; constrain[locator, ptA, ptB]) &]],
   Locator[Dynamic[ptB, (ptB = #; constrain[locator, ptA, ptB]) &]],
   Locator[
    Dynamic[locator, (locator = #; constrain[locator, ptA, ptB]) &]]},
  PlotRange -> 2,
  ImageSize -> 250]
 ]

enter image description here

share|improve this answer

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.