Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Continuing the discussion started in the thread here, I've tried to recreate the code from scratch. I thus looked to constrain the movement of a locator to the graph defined by

f[t_] := t {Cos[10 t], Sin[10 t]}

If the locator is at point pt, then

Table[{t,Norm[f[t] - pt]}, {t, 0, 2, 0.001}]

is a list of couple {t, distances}, which can be sorted with Sort and the t-value can be found back using

{t, Norm[f[t] - pt]}
, {t, 0, 2, 0.001}], (#1[[2]] < #2[[2]]) &]]]

Changing the variable pt by # to create a Pure Function used by the second argument of the Locator command, I tried the code

 ParametricPlot[f[t], {t, 0, 2}]
    ptt =
            {t, Norm[f[t] - #]}
            , {t, 0, 2, 0.001}], (#1[[2]] < #2[[2]]) &]]]]) &

which doesn't work at all. I think there is an error due to expansions of some sorts, but don't know where. Any help with this? The answer found in the link above is working, of course, but I'm trying to find something "shorter", if possible.

All help, as always, very much appreciated!

share|improve this question
up vote 3 down vote accepted

You're missing a Dynamic around ptt and the update function. You also have a misplaced parenthesis in your update function.

ptt = {0., 0.};
f[t_] := t {Cos[10 t], Sin[10 t]}
Show[ParametricPlot[f[t], {t, 0, 2}], 
           (ptt = f[First[First[Sort[Table[{t, Norm[f[t] - #]}, {t, 0, 2, 0.001}],
                                     (#1[[2]] < #2[[2]]) &]]]]) &]


Your approach can be sped up by storing the evaluations of f[t] instead of recalculating them each time the Locator moves:

ptt = {0., 0.};
f[t_] := t {Cos[10 t], Sin[10 t]}
fvalues = f /@ Range[0, 2, 0.001];
Show[ParametricPlot[f[t], {t, 0, 2}], 
    Dynamic[ptt, (ptt = First @ SortBy[fvalues, Function[f0, Norm[f0 - #]]]) &]

Even more efficiency can be obtained by using Nearest instead of sorting, as in my answer to the linked question. You can apply Nearest to fvalues above or the values already calculated by ParametricPlot, which I get below using Cases.

ptt = {0., 0.};
f[t_] := t {Cos[10 t], Sin[10 t]}
plot = ParametricPlot[f[t], {t, 0, 2}];
ptfn = Nearest @ First @ Cases[plot, Line[p_] :> p, Infinity];
Show[plot, Graphics[{Locator[Dynamic[ptt, (ptt = First@ptfn[#]) &]]}]]
share|improve this answer

Your Answer


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.