Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I constrain locators to a limited (but not regular) set of positions?

In Mathematica, locators can be constrained to certain screen regions via the parameters of LocatorPane (See LocatorPane documentation.)

A list of three ordered pairs {{{minX, minY}, {maxX, maxY}, {dX, dY}}} is usually the key to determining the behavior of locators. {minX, minY} and {maxX, maxY} set the region. {dX, dY} sets the jump size: zero for unrestrained, any other positive number for the size of each hop.

In the code below, {{{-.9, 0}, {1, 0}, {0, 0}}} sets the region and jumps for the locator pts. The first two ordered pairs limit the locators to the interval [-9, 1] on the number line. The ordered pair {0, 0} imposes no additional constraints on either of the locators. However, because the y values can only be zero, due to the region defined by the first two items, neither locator is free to leave the x-axis.

I'd like to confine each locator to x-values in myTicks. (In the full program, myTicks will change over time depending on decisions made by the user.) Because the ticks are not uniformly spaced along x, the issue cannot be solved by setting a constant value for the x-jump. And if the value were take into account the current position of the locator, the next left hop might be different size than the right hop.

myTicks = {-.9, 0, .1, .2, .45, .79, 1};
pts = {{.25, 0}, {.75, 0}};

LocatorPane[Dynamic[pts],
  Graphics[{}, 
    Axes -> {True, False}, 
    PlotLabel -> Row[{"locators at: " , Dynamic[pts[[1, 1]]], " and ", 
       Dynamic[pts[[2, 1]]]}], 
    Ticks -> {myTicks, Automatic}],
{{{-.9, 0}, {1, 0}, {0, 0}}}]

Mathematica graphics

Any suggestions would be appreciated!

like image 988
DavidC Avatar asked Mar 10 '11 18:03

DavidC


2 Answers

This appears to work.

myTicks = {-.9, 0, .1, .2, .45, .79, 1};

DynamicModule[{p = {.25, 0}, p2 = {.75, 0}},
 LocatorPane[Dynamic[{p, p2}], 
  Graphics[{}, Axes -> {True, False}, 
   PlotLabel -> 
    Row[{"locators at: ", 
      Dynamic[p[[1]] = Nearest[myTicks, p[[1]]][[1]]], " and ", 
      Dynamic[p2[[1]] = Nearest[myTicks, p2[[1]]][[1]]]}], 
   Ticks -> {myTicks, Automatic}], {{{-.9, 0}, {1, 0}}}, ContinuousAction -> False]
]
like image 66
Mr.Wizard Avatar answered Nov 03 '22 16:11

Mr.Wizard


Let's try this:

pts = {{0, 0}, {10, 0}};
myTics = Table[{x, 0}, {x, 0, 10, 5}];
LocatorPane[Dynamic[pts],
 ListPlot[myTics, PlotRange -> {{-1, 11}, {-1, 1}}, 
  PlotStyle -> Directive[PointSize[.07], Red],
  Epilog -> {PointSize[.05], Blue, h = Point[Dynamic[{Nearest[myTics, pts[[1]]]}]], 
             PointSize[.03], Yellow, j = Point[Dynamic[{Nearest[myTics, pts[[2]]]}]], 
             Black, 
              Text[{"locators at: ", Dynamic[h[[1, 1]]], " and ",Dynamic[j[[1, 1]]]}, 
                    {5, .5}]}],
 Appearance -> None]

enter image description here

like image 43
Dr. belisarius Avatar answered Nov 03 '22 18:11

Dr. belisarius