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$ 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$ Commented Jul 3, 2015 at 9:15
  • $\begingroup$ possible duplicate of LocatorPane and PlotRange $\endgroup$ 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$ 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$ Commented Jul 5, 2015 at 23:50

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.