I want to make a LocatorPane
which allows the user to move the locators, with the restriction that the locators can only be moved to integer coordinates. However, I cannot figure out how to use the second argument of Dynamic
when the first argument is a list of points. Is there some specific syntax that I use in the second argument to refer to the part of the list corresponding to the locator currently being moved? And in the pure function, will #
only refer to the new value of the locator currently being moved, or the new value of the whole list of points? Sorry if this is a dumb question/has been asked before, I am new to Mathematica (and programming in general) and have been searching for hours for an answer to this question.
1 Answer
#
refers to the whole list of point. Here is a different example, that shows how the second argument of Dynamic
can be used inside a LocatorPane
with multiple Locator
s:
DynamicModule[{pt = {{1, 1}/2, {-1, 1}/2, {1, -1}/2}},
{LocatorPane[Dynamic[pt, (pt = Normalize /@ #) &], Graphics[{Gray, Disk[]}],
LocatorAutoCreate -> True], Dynamic[pt]}]
If you only want to restrict the last Locator
(the latest one added to the list):
DynamicModule[{pt = {{1, 1}/2, {-1, 1}/2, {1, -1}/2}},
{LocatorPane[Dynamic[pt, (pt = #; pt[[-1]] = Normalize[Last@#]) &],
Graphics[{Gray, Disk[]}], LocatorAutoCreate -> True], Dynamic[pt]}]
One could also just restrict the movement of the Locator
that is currently being moved, but that requires saving the last state in an additional variable and checking which point actually changed, which makes it more complicated:
DynamicModule[{pt = {{1, 1}/2, {-1, 1}/2, {1, -1}/2}, npt, p, nr},
{LocatorPane[
Dynamic[pt, (npt = #;
nr = First@Pick[Range@Length[npt], UnitStep /@ -Abs[pt - npt], {0, 0}];
pt[[nr]] = Normalize[npt[[nr]]]) &],
Graphics[{Gray, Disk[]}], LocatorAutoCreate -> True], Dynamic[pt]}]