2011-02-23 45 views
9

什麼是在動態設置中異步應用連續改進到Graphics對象的最簡單方法(並且如果輸入在計算時發生變化,則放棄對不需要的結果的評估)?Mathematica:動態圖形的異步增量生成

舉一個簡單的例子,考慮一下:

speed[r_] := [email protected]{Red, Circle[{0, 0}, r]} 
qualityA[r_] := (Pause[1]; [email protected]{Red, Disk[{0, 0}, r]}) 
qualityB[r_] := (Pause[1]; [email protected]{Black, Circle[{0, 0}, r]}) 
Manipulate[Show[ 
    ControlActive[speed[r], {qualityA[r], qualityB[r]}], 
    PlotRange -> {{-1, 1}, {-1, 1}} 
    ], {{r, .5}, 0, 1}] 

Mathematica graphics

如何評估qualityAqualityB連續,並且其輸出追加到顯示器時,它已經準備好?

Abort對不需要的結果的評估的積分,以及允許多次計算結果的一部分,以便在釋放對照之後,我會看到例如, {qualityA[r]}然後{qualityA[r],qualityB[r]},最後是{qualityA2[r],qualityB[r]}

回答

5

我的同事婁,動態的專家,建議這個簡潔答案:

Manipulate[ 
ControlActive[ 
    Graphics[{LightRed, Circle[{0, 0}, r]}, 
    PlotRange -> {{-1, 1}, {-1, 1}}], 
    DynamicModule[{exprs = {Red, Circle[{0, 0}, r]}, rr = r}, 
    Graphics[Dynamic[exprs], PlotRange -> {{-1, 1}, {-1, 1}}], 
    Initialization :> (Pause[1]; 
    AppendTo[exprs, {Red, Disk[{0, 0}, rr]}]; Pause[1]; 
    AppendTo[exprs, {Black, Circle[{0, 0}, rr]}]), 
    SynchronousInitialization -> False]], {{r, 0.5}, 0, 1}] 

工作原理:

當不ControlActive,動態表達式的結果是DynamicModule。用於優化圖形的代碼包含在DynamicModule的Initialization選項中。 SynchronousInitialization -> False使此初始化異步運行。

在DynamicModule中重命名rr = r有兩個作用。首先,它使結果始終取決於Manipulate變量r。其次,你可以檢查rr != r決定用戶是否已經移動初始化期間滑塊,和早期流產,節省計算時間:

Manipulate[ 
ControlActive[ 
    Graphics[{LightRed, Circle[{0, 0}, r]}, 
    PlotRange -> {{-1, 1}, {-1, 1}}], 
    DynamicModule[{exprs = {Red, Circle[{0, 0}, r]}, rr = r}, 
    Graphics[Dynamic[exprs], PlotRange -> {{-1, 1}, {-1, 1}}], 
    Initialization :> (If[rr =!= r, Abort[]]; Pause[1]; 
    AppendTo[exprs, {Red, Disk[{0, 0}, rr]}]; If[rr =!= r, Abort[]]; 
    Pause[1]; AppendTo[exprs, {Black, Circle[{0, 0}, rr]}]), 
    SynchronousInitialization -> False]], {{r, 0.5}, 0, 1}] 

我希望這有助於。

+0

這一個我不能打破!我真的希望你的第一個人能夠工作 - 但正如前面提到的,它在'猴子測試'上死了。這個我可以儘可能多地擺弄我想要的東西,並且一直按照預期行事。非常感謝你爲此而努力! – Janus 2011-02-25 08:26:51

2

真的很好的問題。

我可能忽略了一個更簡單的方法。經常有一個當涉及到動態......但這裏是我的建議:在這種情況下quality(範圍爲0到最大質量,2:

DynamicModule[{quality = 0, exprs = {}}, 
Manipulate[ 
    Show[ 
    ControlActive[ 
    exprs = {}; quality = 0; [email protected]{Red, Circle[{0, 0}, r]}, 
    Switch[quality, 
    0, Pause[1]; quality = 1; 
    AppendTo[exprs, [email protected]{Red, Disk[{0, 0}, r]}], 
    1, Pause[1]; quality = 2; 
    AppendTo[exprs, [email protected]{Black, Circle[{0, 0}, r]}], 
    _, r]; 
    exprs 
    ], 
    PlotRange -> {{-1, 1}, {-1, 1}}], 
    {{r, .5}, 0, 1} 
    ] 
] 

首先,我們定義一些變量控制日益高品質的圖形)和exprs(要顯示的表達式列表,就像在你的例子中一樣)。

現在請注意在ControlActive的兩種情況下會發生什麼:

當ControlActive,結果是一樣的你,除了我們藉此機會重新與「高品質」的圖形qualityexprs

當不ControlActive,動態表達式求

code; exprs 

該表達式具有以下主要特性。

  1. 它每次都返回列表exprs
  2. 每次對code進行評估時,它都會通過在exprs之後附加內容來改進圖形。
  3. 每次評估code時,至少有一個變量是code; exprs(如quality)中包含的詞彙變量。這意味着Dynamic將繼續並再次評估我們的動態表達式,並且再一次,直到...
  4. 最終code評估沒有在code; exprs詞彙上包含的任何變量的變化。這意味着Dynamic將停止重新評估。
  5. 詞彙最終評估包含r。 (通過交換機中其他無用的默認情況下,_, r。)這對於使滑塊仍然觸發更新很重要。

試一試,讓我知道如果這對你有用。

編輯:你使用什麼版本的Mathematica?我在上面的代碼的行爲中看到了一些版本依賴性。

編輯2:我問了一個關於Dynamic的專家,他找到了一個更好的方法,我將在一個單獨的答案中描述。

+0

謝謝,安德魯!這看起來非常像我試圖得到的想法。不幸的是,它不適合我(v8.0,64位OS-X):第一次移動釋放輪很好,但隨後滑塊停止跟隨,接下來的一切都停止了......並像往常一樣使用Dynamics,我不知道什麼是錯的:) – Janus 2011-02-24 01:16:04