6
$\begingroup$

If one uses a stand-alone locator and needs it to only be movable along a curve, say, defined by a function f[x], one can use a simple construct:

Graphics@Locator[Dynamic[pt, (pt = {#[[1]], f[#[[1]]]}) &]]

If one, instead uses a Manipulatestatement with the Locator as a control:

Manuipulate[expression,{{pt, {0.5, 0.5}, {0, 0}, {1, 1}}, Locator}]

where expressionis some graphics and the initial point {0.5,0.5} lies somewhere inside it, the locator may be moved unrestricted between the points {0, 0} and {1, 1}.

My question: how to restrict the motion of the Locator along the line, when using the Locator generated within the Manipulate statement?

To be precise, let it be the line f[x_]:=x?

Comment: I understand that this may be easily done by means of a slider or alike. I would like, however, to have it controlled by a locator.

Comment 2: My question gave rise to a suspect of being a duplicate. Indeed, there were several related questions discussing how to restrict the locator behavior, and solutions are known. The difference is that those solutions always treated the Locators as stand-alone graphics objects. In contrast my question addresses the situation when Locator is fixed as a control in the Manipulate statement. Astonishingly it appears that in this case no solution was so far available.

$\endgroup$
6
  • $\begingroup$ DynamicModule version, do you really insist on Manipulate? $\endgroup$
    – Kuba
    Commented Jul 3, 2015 at 8:57
  • $\begingroup$ @Feyre Could you kindly show an example? $\endgroup$ Commented Jul 3, 2015 at 8:58
  • $\begingroup$ @Kuba, Yes, the locator in question is a part of a large demonstration including a number of different components. It is convenient to keep everything within Manipulate. Apart from that, as it might be clear from my question, I suddenly realized that I know how to do it outside of Manipulate, but have no idea of what to do inside. $\endgroup$ Commented Jul 3, 2015 at 9:00
  • $\begingroup$ @AlexeiBoulbitch Proper exampley now in answer. That is what you meant right? $\endgroup$
    – Feyre
    Commented Jul 3, 2015 at 9:15
  • $\begingroup$ possible duplicate of LocatorPane and PlotRange $\endgroup$
    – m_goldberg
    Commented Jul 3, 2015 at 16:26

1 Answer 1

9
$\begingroup$

The option for a Manipulate control, that mimics the functionality of the second argument to Dynamic is TrackingFunction.

f[x_] := Sin[x]

Manipulate[
 Column[{Show[Plot[f[x], {x, 0, 2 Pi}, Axes -> False, Frame -> True]], p}], 
 {{p, {0, 0}}, Locator, TrackingFunction -> (p = {First@#, f@First@#}; &)}]

enter image description here


Using only Manipulate and no Dynamic

f[x_] := Sin[x]

Manipulate[
 Show[Plot[f[x], {x, 0, 2 Pi}, Axes -> False, Frame -> True], 
  Graphics[{Locator[{First@p, f[First@p]}]}]], 
 {{p, {0, 0}}, Locator, Appearance -> None}]

Out

If the position of the displayed Locator is needed in several parts of the code inside Manipulate, the following implementation is more convenient

Manipulate[
 Module[{locatorPos},
  locatorPos = {First@p, f[First@p]}; 
  Column[{Show[Plot[f[x], {x, 0, 2 Pi}, Axes -> False, Frame -> True],
      Graphics[{Locator[locatorPos]}]], locatorPos}]], 
 {{p, {0, 0}}, Locator, Appearance -> None}]

Two more implementations, that do use Dynamic to restrict the Locator position to the line given by f.

Manipulate[
 Column[{Show[{Plot[f[x], {x, 0, 2 Pi}, Axes -> False, Frame -> True],
      Graphics[Locator[Dynamic[p, (p = {First@#, f[First@#]}) &]]]}], p}],
 {{p, {0, 0}}, None}]

Manipulate[
 Column[{Show[Plot[f[x], {x, 0, 2 Pi}, Axes -> False, Frame -> True]], pPos}],
 {{p, {0, 0}}, {0, Last@pPos}, {2 Pi, Last@pPos}, Locator},
 {{pPos, {Dynamic@First@p, Dynamic@f[First@p]}}, None}]
$\endgroup$
7
  • $\begingroup$ Thank you, that' s sly. So, you draw a stand-alone locator, (just as I described above), while making the Manipulate one invisible. Smart, thank you. $\endgroup$ Commented Jul 3, 2015 at 13:00
  • $\begingroup$ It is unfortunately not the intended functionality, since such a locator picks up an wrong coordinate, cf. ` f[x_] := Sin[x]; Manipulate[ Column[{ Show[Plot[f[x], {x, 0, 2 Pi}, Axes -> False, Frame -> True], Graphics[{Locator[{First@p, f[First@p]}]}]], p }], {{p, {0, 0}}, Locator, Appearance -> None}] ` $\endgroup$ Commented Jul 3, 2015 at 13:09
  • $\begingroup$ @AlexeiBoulbitch Please see my edit. You chose the coordinates of the wrong Locator to be displayed as a part of your Column. $\endgroup$
    – Karsten7
    Commented Jul 3, 2015 at 14:07
  • $\begingroup$ @ Karsten 7 Should I understand that Manipulate itself contains no such a simple mechanism that would allow that? Is it at least you vision? $\endgroup$ Commented Jul 3, 2015 at 14:34
  • 1
    $\begingroup$ @AlexeiBoulbitch I just stumbled upon a Manipulate controls option introduced in v. 10.0, that does exactly what you asked for. $\endgroup$
    – Karsten7
    Commented Jul 5, 2015 at 23:50

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.