3

An extension of this question, I'd like to create multiple locators as per the example below:

Manipulate[
 With[{pts =  Append[#, First[#]] &@
 Table[{r {Cos[phi], Sin[phi]}, phi/(2 Pi)}, {phi, 0, 2 Pi, 
   1/10}, {r, 0, 1, 1/10}]}, 
 DynamicModule[{constrain, dots = {{.5, .5}}}, 
 constrain = If[Norm[#] < 1, #, Normalize[#]] &;
 LocatorPane[Dynamic[dots, (dots = constrain /@ #) &], 
 Graphics[{Polygon[{{0, 0}, First[#1], First[#2]}, 
     VertexColors -> (Hue /@ {{0, 0, 1}, Last[#1], Last[#2]})] & @@@
    Partition[pts[[All, -1, {1, 2}]], 2, 1], 
  Dynamic[{EdgeForm[Black], 
    Hue[Module[{a, b}, b = (List @@@ dots)[[1]]; 
       a = Quiet@(180 ArcTan[#2/#]/Pi) & @@ b; 
       If[Positive[b[[1]]] && Positive[b[[2]]], a, 
        If[Negative[b[[1]]] && Positive[b[[2]]], 180 + a, 
         If[Negative[b[[1]]] && Negative[b[[2]]], 180 + a, 
          If[Positive[b[[1]]] && Negative[b[[2]]], 360 + a, 
           If[b[[2]] == 0 && Positive[b[[1]]], 360, 
            If[b[[1]] == 0 && Positive[b[[2]]], 360/4, 
             If[b[[2]] == 0 && Negative[b[[1]]], 360/2, 
              If[b[[1]] == 0 && Negative[b[[2]]], 360/4]]]]]]]]]/360, 
    Evaluate@EuclideanDistance[{0, 0}, dots[[1]]], b], 
    Disk[#, Scaled[.05]] & /@ dots}]}], 
Appearance -> None]]], {{b, 1}, 0, 1}, ControlPlacement -> Top]

ie, the aim is to make a dynamic version of this:

I have tried

... DynamicModule[{constrain, dots = {{.5, .5}}, dots1 = {{-.5, .5}}}, 
constrain = If[Norm[#] < 1, #, Normalize[#]] &;
LocatorPane[
Dynamic[{dots, (dots = constrain /@ #) &}, {dots1, (dots1 = 
   constrain /@ #) &}], Graphics[ ...

but syntax clearly isn't right. Not sure where to go from here.

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
martin
  • 8,678
  • 4
  • 23
  • 70

1 Answers1

6
ClearAll[wheel, constrain, hue, saturation, disk]

wheel = With[{pts = Append[#, First[#]] & @
   Table[{r {Cos[phi], Sin[phi]}, phi/(2 Pi)}, {phi, 0, 2 Pi, 1/10}, {r, 0, 1, 1/10}]},
   Polygon[{{0, 0}, First[#1], First[#2]}, 
      VertexColors -> (Hue /@ {{0, 0, 1}, Last[#1], Last[#2]})] & @@@ 
    Partition[pts[[All, -1, {1, 2}]], 2, 1]];

constrain = If[Norm[#] < 1, #, Normalize[#]] &;

hue = Module[{a = Quiet @ (180 ArcTan[#2/#]/Pi) & @@ #, signs = Sign[#]},
    Switch[signs, {1, 1}, a, {-1, 1 | -1}, 180 + a, {1, -1}, 
      360 + a, {1, 0}, 360, {-1, 0}, 360/2, {0, 1 | -1}, 360/4]/360] &;

saturation = Norm @ # &;

disk[brightness_] := {EdgeForm[Black], Hue[hue@#, saturation@#, brightness],
   Disk[#, Scaled[.05]]} &;

Manipulate[DynamicModule[{dots = {{.5, .5}}},
  LocatorPane[Dynamic[dots, (dots = constrain /@ #) &], 
   Graphics[{wheel, Dynamic[disk[brightness] /@ dots]}, 
    PlotRange -> {{-1.2, 1.2}, {-1.2, 1.2}}], 
   Appearance -> None, LocatorAutoCreate -> True]], 
 {{brightness, 1}, 0, 1}, ControlPlacement -> Top]

enter image description here

Update: Controlling the number of locators with a slider we can have a slider to control brightness of each locator:

Manipulate[DynamicModule[{dots = RandomPoint[Disk[], n]}, 
  LocatorPane[Dynamic[dots, (dots = constrain /@ #) &], 
   Graphics[{wheel, Dynamic[Table[disk[b[i]] @ dots[[i]], {i, n}]]}, 
    PlotRange -> {{-1.2, 1.2}, {-1.2, 1.2}}], Appearance -> None, 
   LocatorAutoCreate -> False]],
 {{b, b}, None}, 
 {{n, 5}, 1, 10, 1},
 Dynamic @ Column @ Table[With[{i = i}, 
     Control[{{b, b, Dynamic @ Row[{"b[", i, "]"}]}, 0, 1, 
       Slider[Dynamic[b[i]], ##2] &}]], {i, n}], 
 ControlPlacement -> Left, Initialization :> {Do[b[i] = 1, {i, n}]}]

enter image description here

where I use the approach in this answer by Michael E2 to specify a list of controls without having to explicitly list them.

kglr
  • 394,356
  • 18
  • 477
  • 896
  • thank you :) Is it possible to create a new brightness slider for each added locator? – martin Jan 29 '21 at 22:37
  • @martin, it is possible if the number of locators is fixed. If you want to add/remove locators (and sliders) dynamically it is a huge challenge to keep track of the matching between locators and sliders. – kglr Jan 29 '21 at 22:45
  • yes, that makes sense. How would I go about creating a fixed number of locators? – martin Jan 29 '21 at 22:50
  • not sure about syntax on multiple locators – martin Jan 29 '21 at 23:01
  • 2
    @martin, please see the update. – kglr Jan 29 '21 at 23:37
  • thank you - will study syntax! – martin Jan 30 '21 at 00:48
  • @klgr that's great - I find that I have to start with n=10 though, otherwise I get error boxes when increasing n. They do disappear after moving them, not sure why that might be though. – martin Jan 30 '21 at 12:37
  • 1
    @martin, I think replacing {Do[b[i] = 1, {i, n}]} with {Do[b[i] = 1, {i, 10}]} should fix it. – kglr Jan 30 '21 at 20:36