Message Boards Message Boards

0
|
5552 Views
|
7 Replies
|
2 Total Likes
View groups...
Share
Share this post:

How to enable/disable locators independently in manipulate

Posted 10 years ago

I am trying to enable/disable locators inside Manipulate. However, when I try the following code, either both locators are disabled, or both are enabled.

Manipulate[Graphics[{Line[{p1, p2}]}], {{p1, {0, 0}}, Locator, Enabled -> move}, {{p2, {1, 1}}, Locator, Enabled -> ! move}, {move, {False, True}} ]

Is there any way to show locators so that when one of them is enabled, then the other is disabled? As with my previous posts, I need this to be done within the Manipulate. Any suggestions?

POSTED BY: Ferenc Beleznay
7 Replies

Though I am not sure why you are seeing the behavior in Manipulate that you indicate (it appears to be a bug but others should chime in) here is an example of an implementation using DynamicModule [I have updated this code from an earlier version which did not work properly]:

Deploy@DynamicModule[{p1 = {0, 0}, p2 = {1, 1}, move = False},
  Panel@Column[
    {Checkbox[Dynamic[move]],
     Graphics[
      {Locator[Dynamic[p1], Enabled -> Dynamic[move]],
       Locator[Dynamic[p2], Enabled -> Dynamic[! move]],
       Dynamic@Line[{p1, p2}]},
      PlotRange -> 1.1,
      Background -> White]}]]

And, if you want this to be within a Manipulate, you can do something like this:

Manipulate[

 Graphics[{
   Locator[Dynamic[p1], Enabled -> move],
   Locator[Dynamic[p2], Enabled -> ! move],
   Line[{p1, p2}]}, PlotRange -> 1.1, Background -> White],

 {{p1, {0, 0}}, ControlType -> None},
 {{p2, {1, 1}}, ControlType -> None},
 {{move, False}, {False, True}}]
POSTED BY: David Reiss
Posted 10 years ago

Thank you very much, these solutions show me directions. However, when I tried the second one, I ended up with an output, which I could edit. Clicking on the background or the line (and even on the locator point after changing the "move" setting), I get an orange frame. After this, I could resize the background, move the line sometimes without, sometimes with the control points. Is this because p1 and p2 are control variables without being controlled? I am new using Mathematica, I could not figure out what is happening here.

POSTED BY: Ferenc Beleznay

Here is an updated version which, I believe, works (note also that I updated the DynamicModule version in the previous poste since it was not quite correct and did not work). Note both the use of the Deployed -> True option so that the content of the Manipulate is not selectable and also adding a Dynamic around the Line graphics directive. In essence I am forcing the Manipulate to behave exactly like the DynamicModule in the earlier (edited) posting. My guess as to why your original Manipulate did not work properly is that it is trying to create internally a LocatorPane. However, the Enabled option to LocatorPane only applies to all of the locators at once: there is no fine-graned use of Enabled in the LocatorPane which can restrict it to a selected subset of the locators. A WRI developer can perhaps comment....

Manipulate[
 Graphics[{
   Locator[Dynamic[p1], Enabled -> move],
   Locator[Dynamic[p2], Enabled -> ! move],
   Dynamic@Line[{p1, p2}]},
  PlotRange -> 1.1,
  Background -> White],
 {{p1, {0, 0}}, ControlType -> None},
 {{p2, {1, 1}}, ControlType -> None},
 {{move, False}, {False, True}},
 Deployed -> True]
POSTED BY: David Reiss
Posted 10 years ago

Works perfectly, thank you very much. Ferenc

POSTED BY: Ferenc Beleznay
Posted 10 years ago

As I was moving on, I found another step where I am stuck. I am trying to draw a graph using these points as vertices (actually I will need more points, but I need to understand with only two how things work). I put the graphics of the previous example inside a Show[Graphics...,...] (without the Line[{p1,p2}]), and I am trying to create a complete graph (in this case on two vertices), using the points as the coordinates of the vertices. I added the following code as the second argument in Show

CompleteGraph[2,VertexCoordinates->{p1,p2}]

This indeed produced the graph I needed (the two points connected), but unfortunately, moving one of the Locator points around moves the other one, too. I guess it is about not using "Dynamic" in this line of the code, but no matter where I tried to put Dynamic (before CompleteGraph, around {p1,p2}...) I always got an error message that the two graphics could not be combined. My problem is that I don't understand e.g. the syntax Dynamic@Line . I looked at the Dynamic tutorials, but could not find the explanation for this. Can you please suggest something in this special case and for general reading. Unfortunately I do need to use graphs and not only manually connect the points (which I now could do with Line), because I would like to use built in graph algorithms.

POSTED BY: Ferenc Beleznay

The problem here is subtle. Since a **Graph...]** is not a **Graphics[...]** (i.e., the Heads are different) one needs to turn your CompleteGraph into a set of Graphics directives to be placed within a Graphics. Using Show does this implicitly, (i.e., it converts the Graph to a Graphics behind the scenes and then combines them) but to get the control that you need it's probably best to take this step explicitly. (Here is a thread on this on Mathematica Stack Exchange--always a very good resource to go to see what the experts are saying about subtle issues: [http://mathematica.stackexchange.com/questions/25023/convert-graph-to-graphics).

So, with that advice here is the version of your problem with the Line replaced by the CompleteGraph:

Manipulate[
 Graphics[
  {
   Locator[Dynamic[p1], Enabled -> move],
   Locator[Dynamic[p2], Enabled -> ! move],
   Dynamic[
    First[Show[CompleteGraph[2, VertexCoordinates -> {p1, p2}]]]]},
  PlotRange -> 1.1, Background -> White], {{p1, {0, 0}}, 
  ControlType -> None},
 {{p2, {1, 1}}, ControlType -> None},
 {{move, False}, {False, True}},
 Deployed -> True]

Or using the explicit GraphComputation`GraphConvertToGraphics function from the StackExchange advice:

Manipulate[
 Graphics[
  {
   Locator[Dynamic[p1], Enabled -> move],
   Locator[Dynamic[p2], Enabled -> ! move],
   Dynamic[
    First[GraphComputation`GraphConvertToGraphics[
      CompleteGraph[2, VertexCoordinates -> {p1, p2}]]]]},
  PlotRange -> 1.1, Background -> White], {{p1, {0, 0}}, 
  ControlType -> None},
 {{p2, {1, 1}}, ControlType -> None},
 {{move, False}, {False, True}},
 Deployed -> True]

But, remember that GraphComputation`GraphConvertToGraphics is officially undocumented (and hence can vanish or change or have its name changed without notice in any future version of Mathematica), so the first approach (using Show) is safest.

POSTED BY: David Reiss
Posted 10 years ago

Yes indeed, this is exactly what I needed. Thank you very much.

POSTED BY: Ferenc Beleznay
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract