2010 - 09 - 14

Customizing Manipulate´s Animate Bookmarks

In another notebook (see http://www.familydahl.se/mathematica/CustomizingManipulatesAutorun.nb) I have described how to control the Autorun feature of a Manipulate cell. Now I want to control the Animate Bookmarks feature. Animate Bookmarks can be started from the little "+" in a gray circle in the upper right corner of the Manipulate cell. Let us start with a simple Manipulate cell, taken from the Mathematica Help examples. We cannot at first do bookmark animation, because there are no bookmarks defined.

Manipulate[Graphics[Polygon[pt],PlotRange->2],{{pt,{{0,0},{1,0},{1,1},{0,1},{1,-1}}},Locator,LocatorAutoCreate->True}]

With some bookmarks defined, we obtain a very nice bookmark animation. In this example and in the examples below you should activate "Animate Bookmarks" from the little "+" in a gray circle in the upper right corner of the Manipulate cell.

Manipulate[Graphics[Polygon[pt],PlotRange->2],{{pt,{{0,0},{1,0},{1,1},{0,1},{1,-1}}},Locator,LocatorAutoCreate->True},Bookmarks->{"bookmark1":>{pt={{-0.095,-0.38},{1,0},{1.4,1.64},{-1.285,1.64},{1,-1}}},"bookmark2":>{pt={{-0.285,-1.96`},{1,0},{1.4,1.64},{-1.53,0.73},{2.,-1.04}}},"bookmark3":>{pt={{-1.285,1.64},{1,-1},{-0.095,-0.38},{1,0},{1.4,1.64}}}}]

We might also define some coloring. The bookmark animation of the colors will be discontinuous when the coloring is defined as below.

Manipulate[Graphics[{color,Polygon[pt]},PlotRange->2],{{pt,{{0,0},{1,0},{1,1},{0,1},{1,-1}}},Locator,LocatorAutoCreate->True},{{color,Black},{Black->"Black",Red->"Red",Blue->"Blue"}},Bookmarks->{"bookmark1":>{pt={{-0.095,-0.38},{1,0},{1.4,1.64},{-1.285,1.64},{1,-1}},color=Black},"bookmark2":>{pt={{-0.285,-1.96`},{1,0},{1.4,1.64},{-1.53,0.73},{2.,-1.04}},color=Red},"bookmark3":>{pt={{-1.285,1.64},{1,-1},{-0.095,-0.38},{1,0},{1.4,1.64}},color=Blue}}]

If we add one point to the last bookmark, we no longer obtain continuous variation in the animation, not even in the transition between bookmark1 and bookmark2.

Manipulate[Graphics[Polygon[pt],PlotRange->2],{{pt,{{0,0},{1,0},{1,1},{0,1},{1,-1}}},Locator,LocatorAutoCreate->True},
Bookmarks->{"bookmark1":>{pt={{-0.095,-0.38},{1,0},{1.4,1.64},{-1.285,1.64},{1,-1}}},"bookmark2":>{pt={{-0.285,-1.96`},{1,0},{1.4,1.64},{-1.53,0.73},{2.,-1.04}}},"bookmark3":>{pt={{-1.285,1.64},{1,-1},{-0.095,-0.38},{1,0},{1.4,1.64},{-0.5,-0.5}}}}]

Could we gain control over the bookmark animation? Let us introduce a hidden control parameter bmpar. When the polygon is blue, the number of control points are 6, otherwise it is 5. The color control is continuous between bookmark1 and bookmark2, and discrete between boommark2 and bookmark3. The variable bmmode is one whenever a bookmark has been referred to, and zero otherwise.

Manipulate[If[bmmode==1.,pt=ptbmfunc[bmpar];color=colorbmfunc[bmpar];bmmode=0.];
Graphics[{color,Polygon[pt]},PlotRange->2],{{pt,{{0,0},{1,0},{1,1},{0,1},{1,-1}}},Locator,LocatorAutoCreate->True},{{color,Black},{Black->"Black",Red->"Red",Blue->"Blue"}},{{bmpar,1.},1.,3.,ControlType->None},{{bmmode,0.},0.,1.,ControlType->None},
Initialization:>{pt1={{-0.095,-0.38},{1,0},{1.4,1.64},{-1.285,1.64},{1,-1}};
pt1a=Append[pt3,{-1.,-1.}];pt2={{-0.285,-1.96`},{1,0},{1.4,1.64},{-1.53,0.73},{2.,-1.04}};pt2a=Append[pt2,{-0.75,-0.75}];
pt3={{-1.285,1.64},{1,-1},{-0.095,-0.38},{1,0},{1.4,1.64}};pt3a=Append[pt3,{-0.5,-0.5}];
ptbmfunc[bmpar_]:= Piecewise[{{Interpolation[{{1,pt1},{2,pt2},{3,pt3}},InterpolationOrder->2][bmpar],1≤bmpar≤2.3},{Interpolation[{{1,pt1a},{2,pt2a},{3,pt3a}},InterpolationOrder->2][bmpar],2.3<bmpar }}];colorbmfunc[bmpar_]:=Piecewise[{{RGBColor[bmpar-1,0,0],1≤bmpar≤2},{Red,2≤bmpar≤2.3},{Blue,2.3<bmpar }}]},Bookmarks->{"bookmark1":>{bmpar=1.,bmmode=1.},"bookmark2":>{bmpar=2.,bmmode=1.},"bookmark3":>{bmpar=3.,bmmode=1.}}]

The variable Typeset`bookmarkMode$$ is set to "Animator" during bookmark animation. This is useful if we want to add annotation. The annotation is shown just below the "Animate Bookmarks" box, but just during the bookmark animation.

Manipulate[If[Typeset`bookmarkMode$$=!="Animator",ti=0];
If[bmmode==1.,pt=ptbmfunc[bmpar];color=colorbmfunc[bmpar];ti=tibmfunc[bmpar];bmmode=0.];
Graphics[{color,Polygon[pt]},PlotRange->2],Dynamic[If[ti==0,Pane[0,0],annotation[ti]]],{{pt,{{0,0},{1,0},{1,1},{0,1},{1,-1}}},Locator,LocatorAutoCreate->True},{{color,Black},{Black->"Black",Red->"Red",Blue->"Blue"}},{{bmpar,1.},1.,3.,ControlType->None},{{bmmode,0.},0.,1.,ControlType->None},
Initialization:>{pt1={{-0.095,-0.38},{1,0},{1.4,1.64},{-1.285,1.64},{1,-1}};
pt1a=Append[pt3,{-1.,-1.}];pt2={{-0.285,-1.96`},{1,0},{1.4,1.64},{-1.53,0.73},{2.,-1.04}};pt2a=Append[pt2,{-0.75,-0.75}];
pt3={{-1.285,1.64},{1,-1},{-0.095,-0.38},{1,0},{1.4,1.64}};pt3a=Append[pt3,{-0.5,-0.5}];
ptbmfunc[bmpar_]:= Piecewise[{{Interpolation[{{1,pt1},{2,pt2},{3,pt3}},InterpolationOrder->2][bmpar],1≤bmpar≤2.3},{Interpolation[{{1,pt1a},{2,pt2a},{3,pt3a}},InterpolationOrder->2][bmpar],2.3<bmpar }}];colorbmfunc[bmpar_]:=Piecewise[{{RGBColor[bmpar-1,0,0],1≤bmpar≤2},{Red,2≤bmpar≤2.3},{Blue,2.3<bmpar }}];annotation[ti_]:=Switch[ti,0,"",1,"5 control points",2,"5 control points",_,""];
tibmfunc[bmpar_]:=Piecewise[{{1,1≤bmpar≤2.3},{2,2.3<bmpar }}]},Bookmarks->{"bookmark1":>{bmpar=1.,bmmode=1.},"bookmark2":>{bmpar=2.,bmmode=1.},"bookmark3":>{bmpar=3.,bmmode=1.}}]

The "Autorun" feature has become a little bit dull, so we might customize that feature too. We use the procedure from the "Customizing Manipulate´s Autorun" tutorial.

Manipulate[If[Typeset`bookmarkMode$$==="Autorun",autorunfunc[arpar,arparold];arparold=arpar,If[Head[color]==Dynamic,color=First[color]];If[Head[pt]==Dynamic,pt=First[pt]];If[Head[y]==Dynamic,y=First[y]]];
If[Not[MemberQ[{"Animator","Autorun"},Typeset`bookmarkMode$$]],ti=0];
If[bmmode==1.,pt=ptbmfunc[bmpar];color=colorbmfunc[bmpar];ti=tibmfunc[bmpar];bmmode=0.];
Graphics[{color,Polygon[pt]},PlotRange->2],Dynamic[If[ti==0,Pane[0,0],annotation[ti]]],{{pt,Dynamic[ptI]},Locator,LocatorAutoCreate->True},{{color,Dynamic[colorI]},{Black->"Black",Red->"Red",Blue->"Blue"}},{{bmpar,1.},1.,3.,ControlType->None},{{bmmode,0.},0.,1.,ControlType->None},{{arpar,0.},0.,4*Pi,ControlType->None},AutorunSequencing ->{{5,20}},
Initialization:>{colorI=Black;ptI={{0,0},{1,0},{1,1},{0,1},{1,-1}};pt1={{-0.095,-0.38},{1,0},{1.4,1.64},{-1.285,1.64},{1,-1}};
pt1a=Append[pt3,{-1.,-1.}];pt2={{-0.285,-1.96`},{1,0},{1.4,1.64},{-1.53,0.73},{2.,-1.04}};pt2a=Append[pt2,{-0.75,-0.75}];
pt3={{-1.285,1.64},{1,-1},{-0.095,-0.38},{1,0},{1.4,1.64}};pt3a=Append[pt3,{-0.5,-0.5}];
ptbmfunc[bmpar_]:= Piecewise[{{Interpolation[{{1,pt1},{2,pt2},{3,pt3}},InterpolationOrder->2][bmpar],1≤bmpar≤2.3},{Interpolation[{{1,pt1a},{2,pt2a},{3,pt3a}},InterpolationOrder->2][bmpar],2.3<bmpar }}];colorbmfunc[bmpar_]:=Piecewise[{{RGBColor[bmpar-1,0,0],1≤bmpar≤2},{Red,2≤bmpar≤2.3},{Blue,2.3<bmpar }}];annotation[ti_]:=Switch[ti,0,"",1,"5 control points",2,"6 control points",3,"Swirling forth",4,"Swirling back",_,""];
tibmfunc[bmpar_]:=Piecewise[{{1,1≤bmpar≤2.3},{2,2.3<bmpar }}];
autorunfunc[arpar_,arparold_]:=(ptI=Join[({{Cos[arpar],Sin[arpar]},{-Sin[arpar],Cos[arpar]}}.#)& /@{{1.285,0.64},{1,-1}},({{Cos[arpar],-Sin[arpar]},{Sin[arpar],Cos[arpar]}}.#)& /@{{-0.095,-0.38},{1,0},{1.4,1.64}}];
Which[arpar>arparold,colorI=Red;ti=3,arpar<arparold,colorI=Black;ti=4])},Bookmarks->{"bookmark1":>{bmpar=1.,bmmode=1.},"bookmark2":>{bmpar=2.,bmmode=1.},"bookmark3":>{bmpar=3.,bmmode=1.}}]

One issue with defining variables in the Initialization option is the isolation problem. The Manipulate command puts all controls inside a DynamicModuleBox, isolating them from interaction with other cells. However, variables defined by the Initialization option are defined outside the DynamicModule, and they might interfere with outside code and other Manipulate cells, if the same variable names are reused. One way to avoid this is of course to use strictly different names, maybe containing some special string in such a way that it easily replaced. Another method is used here: there is an option CellContext, which might be set to Cell for the whole notebook. Then, a unique default context is used for every cells in the notebook. That can be practical for creating demonstrations, because in a notebook for the Demonstration Project several copies of the same Manipulate cell should be included as thumbnail and snapshots.
The CellContext option can be set by selecting Format -> Option Inspector -> (Selected Notebook, by Category) -> Cell Options -> Evaluation Options -> CellContext. It might alternatively be set by the command SetOptions[EvaluationNotebook[ ], CellContext->Cell]

Please send comments to ingolf.dahl@telia.com.
This notebook, or an updated version, might be available at http://www.familydahl.se/mathematica/CustomizingManipulatesAnimateBookmarks.nb