(* :Title: Flipbook Animation *)

(* :Author: Roman E. Maeder *)

(* :Summary:
   Instead of animating the results of an animation,
   put the individual frames into a graphics array.
*)

(* :Context: Graphics`Animation` (is not a package!) *)

(* :Package Version: 1.2 *)

(* :History:
   Version 1.0 for Programming in Mathematica, Second Ed., 1991.
   Version 1.1 for The Mathematica Journal, V4.4, August 1994.
   Version 1.2 for Mathematica distribution, December 1994.
*)

(* :Keywords: 
  animation
*)

(* :Source: 
    Maeder, Roman E. 1991. Programming in Mathematica, Second Ed.
        Addison-Wesley.
*)

(* :Warning: Redefines $RasterFunction and $AnimationFunction. 
*)

(* :Mathematica Version: 2.2 *)

(* Supersedes: StartUp/FlipBookAnimation.m *)

(* :Discussion: 
The original version distributed with Version 2.2 of Mathematica cannot
display lists of graphics with a prime number of frames in a reasonable
way.  When I developed it, I wasn't aware of the fact that
GraphicsArray (used to assemble the frames in one picture) can cope
with an incomplete last row of frames.  As a consequence, lists of
frames whose length had no proper divisors were displayed in a single
row. Now, a subdivision near the squareroot is found.
The new version defines a global variable,
Graphics`Animation`$Columns that can be used to force the number of
columns displayed to a certain value.
*)


Graphics`Animation`$Columns::usage = 
	"Graphics`Animation`$Columns specifies the number
	of columns in the array of animation frames."

Begin["System`"]

$RasterFunction = Identity

$AnimationFunction = Graphics`Animation`MakeGraphicsArray

If[ !ValueQ[Graphics`Animation`$Columns],
	Graphics`Animation`$Columns = Automatic
]

Begin["Graphics`Animation`Private`"]

Graphics`Animation`MakeGraphicsArray[pics_] :=
    Module[{l = Length[pics], r, row, div, picts},
	If[ l > 1,
	    div = Divisors[l];
	    r = First[ Select[div, # >= Sqrt[l]&] ];
	  ,
	    r = l
	];
	Which[
	    IntegerQ[Graphics`Animation`$Columns] &&
	    1 <= Graphics`Animation`$Columns,
	        row = Graphics`Animation`$Columns,
	    l <= 2,             (* trivial *)
	        row = l,
	    r < 1.4 Sqrt[l], (* can divide exactly *)
		row = r,
	    True,               (* cannot partition exactly *)
		row = Ceiling[Sqrt[l]];
	];
	If[ l < row, (* fill in rest with dummies *)
	    picts = Join[pics, Table[Graphics[{}], {row-l}]];
	   ,
	    picts = Partition[pics, row];
	    If[ Mod[l, row] > 0,    (* leftovers *)
	        AppendTo[picts, Take[pics, -Mod[l, row]]]
	    ];
	];
	Show[GraphicsArray[picts], DisplayFunction -> $DisplayFunction]
    ]

End[] (* Graphics`Animation`Private` *)

End[] (* System` *)

(* Example:

<<FlipBookAnimation.m
Needs["Graphics`Animation`"]
Do[
  Animate[ Plot[Sin[t x], {x, 0, 2Pi}], {t, 1, 2}, Frames -> i],
  {i, 2, 10}]
Graphics`Animation`$Columns = 3
Do[
  Animate[ Plot[Sin[t x], {x, 0, 2Pi}], {t, 1, 2}, Frames -> i],
  {i, 2, 10}]

*)

Null

