What is the simplest way to asynchronously apply consecutive improvements to a Graphics
object in a dynamic setting (and abort the evaluation of the unneeded results if input changes while they are being computed)?
As a simple example, consider this:
speed[r_] := Graphics@{Red, Circle[{0, 0}, r]}
qualityA[r_] := (Pause[1]; Graphics@{Red, Disk[{0, 0}, r]})
qualityB[r_] := (Pause[1]; Graphics@{Black, Circle[{0, 0}, r]})
Manipulate[Show[
ControlActive[speed[r], {qualityA[r], qualityB[r]}],
PlotRange -> {{-1, 1}, {-1, 1}}
], {{r, .5}, 0, 1}]
How can I evaluate qualityA
and qualityB
consecutively, and append their output to the display when it is ready?
Bonus points for Abort
'ing the evaluation of unneeded results, and for allowing a part of the result to be calculated multiple times, so that after releasing the control I would see e.g. {qualityA[r]}
then {qualityA[r],qualityB[r]}
, and finally {qualityA2[r],qualityB[r]}
.
Really good question.
I may be overlooking a simpler way. There often is one when it comes to Dynamic... But here is my suggestion:
DynamicModule[{quality = 0, exprs = {}},
Manipulate[
Show[
ControlActive[
exprs = {}; quality = 0; Graphics@{Red, Circle[{0, 0}, r]},
Switch[quality,
0, Pause[1]; quality = 1;
AppendTo[exprs, Graphics@{Red, Disk[{0, 0}, r]}],
1, Pause[1]; quality = 2;
AppendTo[exprs, Graphics@{Black, Circle[{0, 0}, r]}],
_, r];
exprs
],
PlotRange -> {{-1, 1}, {-1, 1}}],
{{r, .5}, 0, 1}
]
]
First we define some variables controlling increasingly high quality graphics: quality
(ranging to 0 to the maximum quality, 2 in this case), and exprs
(a list of expressions to Show, just as in your example).
Now note what happens in the two cases of ControlActive:
When ControlActive, the result is the same as yours, except we take the opportunity to reset quality
and exprs
relating to the "high quality" graphics.
When not ControlActive, the Dynamic expression evaluates to
code; exprs
This expression has the following key properties.
exprs
every time.code
is evaluated, it improves the graphics by appending something to exprs
.code
is evaluated, at least one of the variables lexically contained in code; exprs
(such as quality
) is changed. This means Dynamic will go ahead and evaluate our dynamic expression again, and again, and again, until ...code
evaluates without any of the variables lexically contained in code; exprs
changing. This means Dynamic will stop re-evaluating.r
. (Via the otherwise useless default case in the Switch, _, r
.) This is important to make the slider still trigger updates.Give it a try and let me know if that works for you.
Edit: What $Version of Mathematica are you using? I see some version dependence in the behavior of my code above.
Edit 2: I asked an expert on Dynamic and he found a better way, which I will describe in a separate answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With