(*******************************************************************
This file was generated automatically by the Mathematica front end.
It contains Initialization cells from a Notebook file, which
typically will have the same name as this file except ending in
".nb" instead of ".m".

This file is intended to be loaded into the Mathematica kernel using
the package loading commands Get or Needs.  Doing so is equivalent
to using the Evaluate Initialization Cells menu command in the front
end.

DO NOT EDIT THIS FILE.  This entire file is regenerated
automatically each time the parent Notebook file is saved in the
Mathematica front end.  Any changes you make to this file will be
overwritten.
***********************************************************************)

(*
This package is a conglomeration of two packages.

"segments" and "estimate" are taken from a package
created at Lafayette College named "Arclength.m." 
The original message from that package follows:

	This package may be distributed freely, but is 
	copyright by Lafayette College, 1994.

(Note that the command "legs" has been removed from 
the package, and the remaining function names have been
capitalized to correspond to standard usage.)

PathAnimate and PathTangentAnimate, and their 3D equivalents, 
were written for use at the University of Minnesota in 2002.  
They may be freely used, but please keep this message intact.
Some day I'll come back and improve the package so that the
coding isn't quite as ugly.  Right now the goal was to get
the commands up and running, and the computers in our lab
are fast enough to deal with a little inefficient code.

I repeat: it's U-G-L-Y.  Hopefully none of my Computer Science
professors will ever see this or they'll try to strip the COSC
credits off my college transcript.

This hodge-podge was created because these commands are used
in one of our labs for MATH 2374, Multivariable Calculus.

Questions to: rogness@math.umn.edu

All non-Lafayette stuff is Copyright 2002 by Jonathan Rogness.
Licensed to University of Minnesota's School of Mathematics
under the GPL.
*)

BeginPackage["Arctools`"];

Segments::usage="Segments[{f[t],g[t]},{t,tmin,tmax},n] plots the
	parametric curve and n line segments which can be used to 
	approximate the length of the curve.  There is no 3D 
	equivalent.";

Estimate::usage="Estimate[{f[t],g[t]},{t,tmin,tmax},n] estimates the 
	length of the curve given parametrically by x = f(t), y = g(t), 
	over the interval tmin < t < tmax, using n subdivisions of the 
	arc.  There is currently no 3D equivalent.";

PathAnimate::usage="PathAnimate[{f[t],g[t]},{t,tmin,tmax},n] animates 
	a particle moving along the curve given parametrically by x = f(t),
	y = g(t), over the interval tmin < t < tmax, using n equally spaced 
	values of t throughout the time interval.  The PlotRange is chosen
	to be as small as possible.";

PathTangentAnimate::usage="PathTangentAnimate[{f[t],g[t]},{t,tmin,tmax},n] 
	animates a particle and its velocity vector moving along the 
	curve given parametrically by x = f(t), y = g(t), over the 
	interval tmin < t < tmax, using n equally spaced values of t 
	throughout the time interval.  The PlotRange is chosen
	to be as small as possible while still showing the vectors.";

PathAnimate3D::usage="PathAnimate[{f[t],g[t],h[t]},{t,tmin,tmax},n].  
	See description of PathAnimate.";

PathTangentAnimate3D::usage="PathTangentAnimate3D[{f[t],g[t],h[t]}, 
	{t,tmin,tmax}, n].  See description of PatTangentAnimate.";

DoAnimation::usage="DoAnimation is called by PathAnimate and
	PathTangentAnimate to actually create their pictures.";
	
Begin["`Private`"];

Off[General::spell];
Needs["Graphics`Arrow`"];

Segments[funclist_,paramlist_,n_,options___] :=
  Block[{tmin, tmax, plotcurve, plotlines, points,
    stepsize, param},
    param = paramlist[[1]];
    tmin = paramlist[[2]]; tmax = paramlist[[3]];
    stepsize = (tmax - tmin)/n;
    plotcurve = ParametricPlot[Evaluate[funclist/.param->t],
      {t,tmin,tmax},PlotStyle->RGBColor[1,0,0],
      DisplayFunction->Identity];
    plotlines = Graphics[{RGBColor[0,0,1], Line[Table[
      funclist/.param->t,
      {t, tmin, tmax, stepsize} ]]}];
    points = Table[Graphics[{RGBColor[0,0,1], Point[
      funclist/.param->t ]}],
      {t, tmin, tmax, stepsize}];
    Show[plotcurve,plotlines, points,options,
      DisplayFunction->$DisplayFunction]
    ]

Estimate[funclist_,paramlist_,n_] :=
  Block[{tmin, tmax, h, param, k},
    param = paramlist[[1]];
    tmin = paramlist[[2]];
    tmax = paramlist[[3]];
    h = (tmax - tmin)/n;
    Sum[N[Sqrt[
      ((funclist[[1]] /. param -> k h) -
       (funclist[[1]] /. param -> (k-1)h))^2
    + ((funclist[[2]] /. param -> k h) -
       (funclist[[2]] /. param -> (k-1)h))^2]],
      {k,1,n}]
    ]

PathAnimate[funclist_,paramlist_,n_,options___]:=
	DoAnimation[funclist,paramlist,n,0,2,options]

PathTangentAnimate[funclist_,paramlist_,n_,options___]:=
	DoAnimation[funclist,paramlist,n,1,2,options]

PathAnimate3D[funclist_,paramlist_,n_,options___]:=
	DoAnimation[funclist,paramlist,n,0,3,options]

PathTangentAnimate3D[funclist_,paramlist_,n_,options___]:=
	DoAnimation[funclist,paramlist,n,1,3,options]

DoAnimation[funclist_,paramlist_,n_,flag_,dim_,options___] :=
  Block[{tmin, tmax, stepsize, param, graph, s, t,
  	f, Df, x, Dx, y, Dy, z, Dz, xmin, xmax, ymin, ymax, zmin, zmax, radius},
    param = paramlist[[1]];
    tmin = paramlist[[2]]; tmax = paramlist[[3]];
    stepsize = (tmax - tmin)/n;

	(*	Note: flag should be True (1) or False (0).
		If it's false, then only the position of the
		particle is animated.  If it's true, then
		the tangent vectors are also shown.
		
		dim(ension) should be either 2 or 3, and should
		correspond to the number of components in the
		parametrization. *)

	(*  These could be done within the later commands,
		but I'm doing them here just to make those commands
		easier to read. Also, I'm going to handle the third
		dimension inefficiently here.  It won't slow the command
		down too much and it's easier to be lazy.  If there's
		a third dimension, we'll use it.  If not we'll double
		up the work in the first dimension. *)

	f[t_]=Evaluate[funclist/.param->t];
	Df[t_]=D[f[t],t];
	x[t_]=f[t][[1]]; Dx[t_]=D[x[t],t];
	y[t_]=f[t][[2]]; Dy[t_]=D[y[t],t];

	Which[dim==2,z[t_]=f[t][[1]]; Dz[t_]=D[z[t],t],
		  dim==3,z[t_]=f[t][[3]]; Dz[t_]=D[z[t],t]];

	Off[ParametricPlot::ppcom];
	Off[ParametricPlot3D::ppcom];
	Off[$MaxExtraPrecision::meprec];
	
	(* Try to determine a good PlotRange.  This isn't a perfect
	method, but Mathematica can't find global extrema, even for
	fairly simple functions on a compact interval.  [I don't want
	to rely on the Experimental package...]  I need two separate
	procedures depending on whether I need to include tangent
	vectors or not.	*)

	xmin=xmax=x[tmin]; ymin=ymax=y[tmin]; zmin=zmax=z[tmin];

	Which[
		flag==0,Do[
					xmin=Min[x[s],xmin];
 	 				xmax=Max[x[s],xmax];
  					ymin=Min[y[s],ymin];
  					ymax=Max[y[s],ymax];
  					zmin=Min[z[s],zmin];
  					zmax=Max[z[s],zmax];
  					,{s,tmin,tmax,stepsize}];, 
		flag==1,Do[
				xmin=Min[x[s]+Dx[s],xmin];
 	 			xmax=Max[x[s]+Dx[s],xmax];
  				ymin=Min[y[s]+Dy[s],ymin];
  				ymax=Max[y[s]+Dy[s],ymax];
  				zmin=Min[z[s]+Dz[s],zmin];
  				zmax=Max[z[s]+Dz[s],zmax];
  				,{s,tmin,tmax,stepsize}];];
  				
  	(*	This is kind of a superfluous step, but we need to increase
  		the ranges just a tad or points on the edge of the box won't
  		be displayed.  These lines also prevent problems if x[t], y[t],
  		or z[t] are constant. *)
  		
  	xmin=xmin-0.1;
  	ymin=ymin-0.1;
  	zmin=zmin-0.1;
	xmax=xmax+0.1;
	ymax=ymax+0.1;
	zmax=zmax+0.1;
	
	Which[dim==2,
			graph=ParametricPlot[f[t],{t,tmin,tmax},
  		    	DisplayFunction->Identity,
    		    AspectRatio->Automatic,
      			PlotRange->{{xmin,xmax},{ymin,ymax}},options],
      	  dim==3,
			graph=ParametricPlot3D[f[t],{t,tmin,tmax},
  		    	DisplayFunction->Identity,
    		    AspectRatio->Automatic,
      			PlotRange->{{xmin,xmax},{ymin,ymax},{zmin,zmax}},options]];

	radius=Min[Abs[xmax-xmin],Abs[ymax-ymin],Abs[zmax-zmin]]/60;
	radius=Min[radius,0.03];
	radius=Max[radius,0.03];
	
	Do[Show[graph,
   	
			If[dim==2,
	    		(* Are we showing Tangent Vectors? *)
 		   		If[flag==1,
 		   				Graphics[ {Hue[0],Arrow[ f[t],f[t]+Df[t] ]} ],
						Graphics[ {PointSize[radius],Point[f[t]]} ]
				  ],
				If[flag==1,
						Graphics3D[ {Hue[0],Line[ {f[t],f[t]+Df[t]} ] }],
						Graphics3D[ {PointSize[radius],Point[f[t]]} ]
				]
			],

			If[dim==2,    Graphics[ {PointSize[radius],Point[f[t]]} ],
						Graphics3D[ {PointSize[radius],Point[f[t]]} ]],
										
	    		DisplayFunction->$DisplayFunction,
        		AspectRatio->Automatic,

			If[dim==2,  PlotRange->{{xmin,xmax},{ymin,ymax}},
						PlotRange->{{xmin,xmax},{ymin,ymax},{zmin,zmax}}],

        	options],
        	{t,tmin,tmax,(tmax-tmin)/n}];
    ];
    
End[(* "`Private`" *)];
EndPackage[ ];




