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.

I was wondering whether it was possible to have a two way control system, whereby one could click and drag both the locator (which would in turn move the sliders), AND click & drag the sliders (which in turn would move the locator). Here is an image of what I would like to achieve:

enter image description here

The code below controls the locator only:

f[x_] := x^2;
Manipulate[n, {n, 1, 20, 1}]
Manipulate[With[{x0 = Clip[p[[1]], {0., 10}]}, 
Plot[f[x], {x, 0, 10}, ImagePadding -> 20, LabelStyle -> (FontFamily -> "Ariel"),
Epilog -> {PointSize[Large], Red,
Tooltip[Point[#], #] &@{x0, f[x0]}}]], {{p, {0, 0}}, Locator, Appearance -> None},
AppearanceElements -> None]

for which I must credit Michael E2 and Timothy Wofford :-)

share|improve this question
    
The code you posted does not correspond to the image. I also do not see any (failed/partially successful) attempt to work this out yourself. There isn't even evidence of research (links to relevant posts, documentation, etc.) This seems to be a pattern with you, and I would like to see more effort on your part in the future. –  Timothy Wofford Oct 20 '13 at 12:29
add comment

1 Answer

up vote 2 down vote accepted

Manipulate does not remember the previous value of its dynamic variables. So we save their values in another variable. Then whenever the Manipulate begins another cycle, we compare the new values to the saved values.

To lock the sliders together we need a function y=f[x] and its inverse x=g[y]. You have to supply both of these relationships; Mathematica will not give you an inverse function.

(* Relationships constraining sliders *)
f[x_] := x^2;
g[y_] := Sqrt[y];

(* External variables for remembering previous values *)
xSave = 0;
ySave = 0;
pSave = {0, 0};

Manipulate[
 (* compare values and handle changes appropriately *)
 If[xx != xSave, xSave = xx; p[[1]] = xx; yy = f[xx]];
 If[yy != ySave, ySave = yy; xx = g[yy]];
 If[p != pSave, pSave = p; xx = p[[1]]; yy = f[xx]];

 (* The manipulated object *)
With[{x0 = Clip[p[[1]], {0., 10}]}, 
  Plot[f[x], {x, 0, 10}, ImagePadding -> 20, 
   LabelStyle -> (FontFamily -> "Ariel"), 
   Epilog -> {PointSize[Large], Red, 
    Tooltip[Point[#], #] &@{x0, f[x0]}}]],

 (* The controls *)
 {xx, 0, 10},
 {yy, 0, 100},
 {{p, {0, 0}}, Locator, Appearance -> None}, 
 AppearanceElements -> None]
share|improve this answer
    
@ Timothy Wofford, Thank you so much - works brilliantly! :-) –  martin Oct 20 '13 at 12:49
    
For the labels, check out the documentation center –  Timothy Wofford Oct 20 '13 at 12:50
add comment

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.