19
$\begingroup$

I've recently stumbled across this site: Koalas to the Max, and the first thought that came to my mind was "I want to recreate this with Mathematica".

As a first step I tried to create a Disk that splits itself up into four disks, when the mouse cursor touches it. Those four disks should in turn split themselves up. Here's what I have so far:

makeDisks[pos_] := makeDisks[1, pos]
makeDisks[level_, pos_] :=
 Module[{
   disk = Disk[pos, 1/level]},
  Mouseover[Dynamic@disk, Dynamic[disk = makeDisks[level + 1, #] & /@ 
   (pos + # & /@ (1/(2 level)) Tuples[{-1, 1}, 2])]]
  ]

(* test with the following *)

 Graphics[{makeDisks[1]},
   PlotRange -> {{-1, 1}, {-1, 1}}]

For the first disk this seems to work just as I want it. For later steps, however, I got the positioning wrong and some of the disks go back to larger ones, when another one is touched. How can these issues be fixed?

As a next step I want to add colors to the disks. Maybe this can be done by using MapIndexed with makeDisks on the ImageData of some image. The colors in each step should probably be the mean values of appropriate subsets of the image data.

Any help to move this little program forward is highly appreciated!

$\endgroup$

2 Answers 2

20
$\begingroup$

Here's a simple way using buttons, for some reason AutoAction is not working so you have to click, anyone know why?

nextPos[p_, r_] := {p + # r/2, r/2} & /@ Tuples[{1, -1}, 2]

DynamicModule[{diskList = {{ {0, 0}, 1}}},
 Graphics[Dynamic[
   Button[{ColorData["Rainbow"][Last@#], Disk @@ #},
      diskList = DeleteCases[Join[diskList, nextPos @@ #], #]
      ,AutoAction -> True
      ] & /@ diskList]]
 ]

circles

The coloring is only based on depth (radius)

Basing color on underlying image:

background = ImageCrop[ExampleData[{"TestImage", "Peppers"}], AspectRatio -> 1];

DynamicModule[{diskList = {{{0, 0}, 1}}}, Graphics[Dynamic[
   Button[{RGBColor@ImageValue[background,First@#, DataRange -> {{-1, 1}, {-1, 1}}],
       Disk @@ #} 
     ,diskList = DeleteCases[Join[diskList, nextPos @@ #], #]
     ,AutoAction -> True] & /@ diskList]]]

pepper

Using code from @Szabolcs comment it's possible to split the disks without clicking:

(* Create at most 2^6=64 disks in a row *) 
rmin = 2^-6;
DynamicModule[{diskList = {{{0., 0.}, 1.}}}, Graphics[Dynamic[
  EventHandler[{RGBColor@ImageValue[background, First@#, DataRange -> {{-1, 1}, {-1, 1}}], 
                Disk @@ #}
    ,{"MouseMoved" :>
      If[Last@# > rmin, diskList =DeleteCases[Join[diskList, nextPos @@ #], #]]}
   ] & /@ diskList]]
]
$\endgroup$
9
  • $\begingroup$ (+1) AutoAction doesn't work here either. But even if it did, wouldn't it trigger a split on every move? In the original, a split is only triggered when the mouse moves into a disk the first time (but not when the mouse happens to be over a newly generated disk) $\endgroup$
    – Szabolcs
    Feb 19, 2013 at 17:08
  • $\begingroup$ @Szabolcs Indeed, potentially it would also create a crazy amount of disks, so would need some minimum r limit $\endgroup$
    – ssch
    Feb 19, 2013 at 17:13
  • $\begingroup$ I mean, this would happen: DynamicModule[{diskList = {{{0, 0}, 1}}}, Graphics[Dynamic[ EventHandler[{ColorData["Rainbow"][Last@#], Disk @@ #}, {"MouseMoved" :> (diskList = DeleteCases[Join[diskList, nextPos @@ #], #])}] & /@ diskList]]] $\endgroup$
    – Szabolcs
    Feb 19, 2013 at 17:14
  • 1
    $\begingroup$ Autoaction seems not working with Graphical Buttons. Test it Module[{i = Disk[]}, #@ Button[Dynamic@i, Dynamic[i = Rectangle[]], AutoAction -> True]] & /@ {Identity, Graphics} $\endgroup$ Feb 19, 2013 at 17:44
  • 2
    $\begingroup$ Sadly it gets progressively slower as the number of disks increases... $\endgroup$
    – Ajasja
    Feb 19, 2013 at 21:03
15
$\begingroup$

Alternative

DynamicModule[{visited = False}, 
    Dynamic@EventHandler[
      If[visited, 
       Thread@Translate[#0@#, {1, -1}~Tuples~2]~Scale~
        0.5, {ColorData["Rainbow"]@Random[], #}], 
      "MouseEntered" :> (visited = True)]] &[Disk[]] // Graphics

Other version. Works "more or less" fine. Read comments

SetAttributes[translateOnHover, HoldFirst];
s : translateOnHover[onVar_, animationLength_, animationRate_: 200][
   prim_] := 
 With[{creationTime = Clock[Infinity]~Refresh~None}, 
  DynamicModule[{visited = False}, 
   Dynamic@If[visited, 
     With[{visitedTime = Clock[Infinity]~Refresh~None}, 
      With[{currentTime := 
         1/animationLength (Clock[{0, visitedTime + animationLength, 
              1`/animationRate}, visitedTime + animationLength, 1] - 
            visitedTime)}, 
       Thread@Translate[s, ({1, -1}~Tuples~2) /. 
           pt : {_, _} :> Dynamic[pt currentTime]]~Scale~
        Dynamic[currentTime /. t_ :> 1 - t + 0.5 t^2]]], 
     EventHandler[{ColorData["Rainbow"]@Random[], prim}, 
      "MouseEntered" :> 
       If[onVar && 
         Refresh[Clock[Infinity], None] - creationTime > 
          animationLength, visited = True]]]]]

With[{animationLength = 0.8, animationRate = 80}, 
  DynamicModule[{on = False}, 
   Column[{Row[{Button["Start", on = True, Enabled -> Dynamic[! on]], 
       Spacer[20], 
       Button["Stop", on = False, Enabled -> Dynamic[on]]}], 
     Graphics[
      translateOnHover[on, animationLength, animationRate][Disk[]], 
      ImageSize -> Medium, PlotRange -> 1.2 {{-1, 1}, {-1, 1}}]}, 
    Alignment -> Center]]] // Panel
$\endgroup$
13
  • $\begingroup$ Nice use of #0! $\endgroup$
    – ssch
    Feb 19, 2013 at 19:06
  • $\begingroup$ What is MouseEntered? Is there a link somewhere to a list of undocumented EventHandler events? $\endgroup$
    – Szabolcs
    Feb 19, 2013 at 20:23
  • $\begingroup$ @Szabolcs it is triggered when the mouse enters, there's also MouseExited. I'm trying to remember where I got that from. $\endgroup$
    – Rojo
    Feb 19, 2013 at 20:24
  • 1
    $\begingroup$ Re your last edit: During animations I get a lot of "shaking", it seems like the plot range may be changing rapidly. For disks next to the edge the whole plot is shaking, for others only the animated part. Do you see this too? $\endgroup$
    – Szabolcs
    Feb 19, 2013 at 20:27
  • 1
    $\begingroup$ @rm-rf The "shaking" is definitely not mac specific. I get it too. (Windows 7, Mma 8) $\endgroup$
    – einbandi
    Feb 19, 2013 at 23:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.