(* This mathematica file creates the file "tangent.anim" to
   demonstrate the statement that "looked at under the microscope
   a differentiable function looks like its tangent line."

   The animation displays the graph of y=x^2 and its
   tangent line through x=3, zooming in on the point (3,9).
   A grid is provided and the tangent line is striped to cue the
   zooming.

   Note: It is advisable to compress the file--animations files are
   big, but generally then compress a lot).

   Suggest viewing command:

     motifps -width 1000 -height 500 tangent.m

   Douglas N. Arnold, 10/11/92, 10/02/94
    
   Douglas N. Arnold  <dna@math.psu.edu>
   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["Tangent`", "Graphics`Animation`", "Graphics`Colors`"]

Begin["Private`"]

(* Describe the individual frames. *)

frame[expr_,x_,x0_,a_,b_,c_,d_,e_,s_,gx_,gy_,ns_] :=
Module[{xmin,xmax,ymin,ymax,nx,deltax,y0,f,g,graph,tangent,
        stripes,point,grid,n},
  f[t_] := (expr /. x -> t);
  g[t_] := y0 + f'[x0](t-x0);
  y0 = f[x0];
  xmin = x0 - s a;
  xmax = x0 + s b;
  ymin = y0 - s c;
  ymax = y0 + s d;
  nx = 100;
  deltax = (xmax - xmin) / nx;
  graph = Line[Table[{xmin + n deltax,f[xmin + n deltax]},{n,0,nx}]];
  tangent = Line[{{xmin,g[xmin]},{xmax,g[xmax]}}];
  stripes = Table[Line[{{x0-a+(n-1)(a+b)/ns,g[x0-a+(n-1)(a+b)/ns]},
     {x0-a+n (a+b)/ns,g[x0-a+n (a+b)/ns]}}],{n,1,ns,2}];
  point = Point[{x0,y0}];
  grid = Join[ Table[Line[{{n,ymin},{n,ymax}}],{n,x0-a,x0+b,(a+b)/gx}],
               Table[Line[{{xmin,n},{xmax,n}}],{n,y0-c,y0+d,(c+d)/gy}] ];
  Graphics[
    Flatten[
      { GrayLevel[.5], Thickness[0.001], grid,
        Magenta, Thickness[0.005], graph,
        Cyan, tangent, Yellow, stripes, Red, PointSize[0.02], point }
    ] , PlotRange -> {{xmin,xmax},{ymin,ymax}}, AspectRatio ->1, 
        Background -> Black,
        PlotRegion -> {{0,1},{0,1}}
  ]
]

(* Create the animations. *)

nframes = 30  (* 20 seems reasonable for a SparcStation 2 with 32 MB,
                larger values give smoother animation, but use more memory *)

ShowAnimation[Table[
      frame[x^2,x,3,5,7,39,81,5,e/5,12,12,20],
        {e,5,5/nframes,-5/nframes}],
  AnimationFunction->(DisplayAnimation["tangent.anim",#]&)]
Print["-- wrote file tangent.anim --"]

(* These lines rasterize each frame separately to ppm format.  They can
   be used to create an MPEG animation file. *)

(*
writetofile[i_] := StringJoin["!rasterps -format ppm > /tmp/graphics/tangent.",
  ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"]
Table[ Display[writetofile[nframes-nframes e/5+1],
     frame[x^2,x,3,5,7,39,81,5,e/5,12,12,20]],
        {e,5,5/nframes,-5/nframes}]
Print["-- rasterized frames from tangent --"]
*)

End[] (* end of context private *)

EndPackage[]
