(* This mathematica file creates the files bounce0.anim, bounce1.anim, and
bounce2.anim which animate a bouncing ball. bounce0.anim only shows
the ball together with a clock and axes. bounce1.anim and the graph,
and bounce2.anim the graph of the derivative as well. (Actually we
show a graph of the derivative divided by 20, so that the same axes
can be used for the function and the derivative.
Note: be sure to compress these files (they are big, but
compress a lot). View the animations with a command like "motifps
bounce0.anim".
The ball is released at time 0 from 100 centimeters. We display
its height versus time over the interval [0,3], measured in second,
although it comes to rest at time 2.4 seconds. The height function
is a piecewise quadratic. It is reasonably realistic, but not meant
to conform to any exact model.
Douglas N. Arnold, 8/29/92, 8/25/94
Douglas N. Arnold
Department of Mathematics
Penn State
University Park, PA 16802
Online documentation related to this file can be found at WWW URL
http://www.math.psu.edu/dna/graphics.html.
*)
BeginPackage["Bounce`", "Graphics`Animation`", "Graphics`Colors`"]
Begin["Private`"]
(* Define the ground contact times. These have been adjusted to give a
fairly realistic bouncing ball, but also to be integers/20. This way we
can animate with frames every 1/20 second and the ball always hits the
ground exactly at a frame time.
*)
xp = {-10, 10, 23, 32, 38, 42, 45, 47, 48}/20
g[x_]:= 0 /; x <= First[xp] || x >= Last[xp]
g[x_]:=
Module[{m},
m = Last[Position[Map[(#= Last[xp]
gp[x_]:=
Module[{m},
m = Last[Position[Map[(# (DisplayAnimation["bounce0.anim",#]&) )
opts1 = ( AnimationFunction -> (DisplayAnimation["bounce1.anim",#]&) )
opts2 = ( AnimationFunction -> (DisplayAnimation["bounce2.anim",#]&) )
(* Define a single frame of the animation. *)
frame[i_,showgraph_,showdgraph_] :=
( x = N[times[[i]]];
y = g[x];
(* Create the graph, a polyline plotting the height of the ball versus time
from time 0 to the present moment. Use the points with integer abscissas
as breakpoints for the polyline except include the present point as
well and include the starting point twice so that Line doesn't get
confused on the first frame when it has only one endpoint. *)
graph = If[showgraph,
{ Blue, Thickness[0.007],
Line[Map[{#,g[#]}& , Prepend[Union[Table[t,{t,0,x,1/20}],{x}],0]]]},
{} ] ;
(* Create the graph of the derivative. This is a bit of a bother since
the derivative is undefined at the break points. *)
dgraph = If[showdgraph,
eps = .005;
m = Last[Position[Map[(#{{xmin,xmax},{ymin,ymax}}, Frame->True] )
(* Create the animation. *)
(* The next three lines will create Mathematica animation files. *)
ShowAnimation[Table[frame[i,False,False],{i,1,Length[times]}],opts0]
ShowAnimation[Table[frame[i,True,False],{i,1,Length[times]}],opts1]
ShowAnimation[Table[frame[i,True,True],{i,1,Length[times]}],opts2]
(* The next lines rasterize each frame separately to ppm format.
These can be used with makempg to create mpeg files. *)
(*
writetofile[i_] := StringJoin["!rasterps -format ppm > bounce0.",ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"]
Table[ Display[writetofile[i],frame[i,False,False]],
{i,1,Length[times]}]
writetofile[i_] := StringJoin["!rasterps -format ppm > bounce1.",ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"]
Table[ Display[writetofile[i],frame[i,True,False]],
{i,1,Length[times]}]
writetofile[i_] := StringJoin["!rasterps -format ppm > bounce2.",ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"]
Table[ Display[writetofile[i],frame[i,True,True]],
{i,1,Length[times]}]
*)
End[] (* end of context private *)
EndPackage[]
(* write an exit message *)
Print["-- wrote files bounce0.anim, bounce1.anim, and bounce2.anim --"]