TransWikia.com

Building dynamic functions

Mathematica Asked on April 21, 2021

When I’m trying to build Dynamic functions (as in this question), I often end up with long repeated lists of dynamic variables, like this:

Grid[{{
LocatorPane[
Dynamic[{p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12}], 
image, Appearance -> {Dynamic@
   Style[Graphics[{White, Disk[{1, 1}, 1.2], 
      RGBColor[PixelValue[image, p1]], Disk[{1, 1}, 1]}, 
     ImageSize -> 20]], 
  Dynamic@Style[
    Graphics[{White, Disk[{1, 1}, 1.2], 
      RGBColor[PixelValue[image, p2]], Disk[{1, 1}, 1]}, 
     ImageSize -> 20]],
  Dynamic@
   Style[Graphics[{White, Disk[{1, 1}, 1.2], 
      RGBColor[PixelValue[image, p3]], Disk[{1, 1}, 1]}, 
     ImageSize -> 20]],
  Dynamic@
   Style[Graphics[{White, Disk[{1, 1}, 1.2], 
      RGBColor[PixelValue[image, p4]], Disk[{1, 1}, 1]}, 
     ImageSize -> 20]], (*...*)

..etc. Is there an elegant workaround for this?

2 Answers

SeedRandom[1];
pts = RandomSample[Tuples@Range[ImageDimensions@image], 9];

DynamicModule[{plist = pts}, 
 LocatorPane[Dynamic[plist], image, 
  Appearance -> Table[With[{i = i}, 
     Graphics[{White, Disk[{1, 1}, 1.2], 
       Dynamic @ RGBColor[PixelValue[image, plist[[i]]]], 
       Disk[{1, 1}, 1]}, ImageSize -> 20]], {i, Length@pts}]]]

enter image description here

DynamicModule[{plist = pts}, 
 Grid[{{Dynamic[ap[pix[image, #] & /@ plist]], 
    Dynamic[cw[pix[image, #] & /@ plist]], 
    LocatorPane[Dynamic[plist], image, 
     Appearance -> Table[With[{i = i}, 
        Graphics[{White, Disk[{1, 1}, 1.2], 
          Dynamic @ RGBColor[PixelValue[image, plist[[i]]]], 
          Disk[{1, 1}, 1]}, ImageSize -> 20]], {i, Length @ pts}]]}}]]

enter image description here

Correct answer by kglr on April 21, 2021

Yes, there is. Controls can often be linked to parts of variables. Taking your previous example:

DynamicModule[{point = {{1, 1}, {100, 100}}}, 
 Grid[{{Dynamic[
     ap[{pix[image, point[[1]]], 
       pix[image, point[[2]]]}]],(*colour wheel added here*)
    Dynamic[cw[{pix[image, point[[1]]], pix[image, point[[2]]]}]], 
    LocatorPane[Dynamic[point], image, 
     Appearance -> {Dynamic @ Style[Graphics[{White, Disk[{1, 1}, 1.2], 
           RGBColor[PixelValue[image, point[[1]]]], Disk[{1, 1}, 1]}, 
          ImageSize -> 20]], 
       Dynamic@Style[ Graphics[{White, Disk[{1, 1}, 1.2], 
           RGBColor[PixelValue[image, point[[2]]]], Disk[{1, 1}, 1]}, 
          ImageSize -> 20]]}]}}]]

You can also use associations to make it a bit easier to read:

DynamicModule[{point = <|"p1" -> {1, 1}, "p2" -> {100, 100}|>}, 
 Grid[{{Dynamic[
     ap[{pix[image, point["p1"]], 
       pix[image, point["p2"]]}]],(*colour wheel added here*)
    Dynamic[cw[{pix[image, point["p1"]], pix[image, point["p2"]]}]], 
    LocatorPane[Dynamic[{point["p1"], point["p2"]}], image, 
     Appearance -> {Dynamic @ Style[Graphics[{White, Disk[{1, 1}, 1.2], 
           RGBColor[PixelValue[image, point["p1"]]], Disk[{1, 1}, 1]},
           ImageSize -> 20]], 
       Dynamic@Style[Graphics[{White, Disk[{1, 1}, 1.2], 
           RGBColor[PixelValue[image, point["p2"]]], Disk[{1, 1}, 1]},
           ImageSize -> 20]]}]}}]]

Note, however, that you can't do something like TrackedSymbols :> {point[[1]]}. So if you have many interactive elements, it can be tricky to tell Mathematica to selectively update only parts of the interface: when point changes, everything will have to be updated, even if you know in advance that certain elements don't need it.

Answered by Sjoerd Smit on April 21, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP