(* This mathematica file creates the files secants1.anim, ..., secants5.anim, which illustrate the converge of secants to the tangent. The first two show the secants approaching the tangent on a parabola. The only difference between these files is that the tangent itself is drawn in the second one, along with the curve, moving secants, and a display of the slope of the secant. The third file shows non-convergence at an isolated point of nondifferentiabily but with left and right handed derivatives finite. The fourth file shows the case with the tangent is vertical. The final one is like the first, but with a parabola that arose in an earlier discussion of a bouncing ball. Douglas N. Arnold, 8/29/92, 9/2/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["Differential`", "Graphics`Animation`", "Graphics`Colors`"] Begin["Private`"] SimpleGraph[ fct_, var_, dr_ ] := Module[ {t,xmin, xmax, ymin, ymax }, {{xmin,xmax},{ymin,ymax}} = dr; { Thickness[0.007], Line[Table[{t,fct/.var->t},{t,xmin,xmax,(xmax-xmin)/75}]] } ] PointSlopeLine[ pt_, slope_, dr_ ] := Module[ { x, y, xmin, xmax, ymin, ymax }, {{xmin,xmax},{ymin,ymax}} = dr; {x,y} = pt; Line[ {{xmin-.1,slope (xmin-.1 - x) + y}, {xmax+.1,slope (xmax+.1 - x) + y}}] ] TangentLine[ fct_, var_, x0_, dr_ ] := Module[ { slope }, slope = D[fct,var]/.var->x0; PointSlopeLine[ {x0,fct/.var->x0}, slope, dr ] ] SecantLine[ fct_, var_, x0_, x1_, dr_ ] := Module[ { slope }, If[ x0 == x1, Return[ TangentLine[fct,var,x0,dr]]]; slope = ((fct/.var->x0) - (fct/.var->x1))/(x0-x1); PointSlopeLine[ {x0,fct/.var->x0}, slope, dr ] ] SecantFrame[ fct_, var_, x0_, x1_, dr_] := ( {{xmin,xmax},{ymin,ymax}} = dr; y0 = fct/.var->x0; y1 = fct/.var->x1; slope = (y1-y0)/(x1-x0); Graphics[ Flatten[ { Thickness[0.007],PointSize[0.022], Cyan, SimpleGraph[fct,var,dr], Magenta, SecantLine[fct, var, x0, x1, dr ], Green, Point[{x0,y0}], Yellow, Point[{x1,y1}], Green, Point[{x0,ymin}], Yellow, Point[{x1,ymin}], Yellow,Text[PaddedForm[N[slope],{5,3}],Scaled[{.2,.9}],{-1,0}] } ], PlotRange->dr,Frame->True, Background->Black,DefaultColor->White, DefaultFont->{"Courier-Bold",24.} ] ) SecantTangentFrame[ fct_, var_, x0_, x1_, dr_] := ( {{xmin,xmax},{ymin,ymax}} = dr; y0 = fct/.var->x0; y1 = fct/.var->x1; slope = (y1-y0)/(x1-x0); Graphics[ Flatten[ { Thickness[0.007],PointSize[0.022], Cyan, SimpleGraph[fct,var,dr], Green, TangentLine[fct,var,x0,dr], Magenta, SecantLine[fct, var, x0, x1, dr ], Green, Point[{x0,y0}], Yellow, Point[{x1,y1}], Green, Point[{x0,ymin}], Yellow, Point[{x1,ymin}], Yellow,Text[PaddedForm[N[slope],{5,3}],Scaled[{.2,.9}],{-1,0}] } ], PlotRange->dr,Frame->True, Background->Black,DefaultColor->White, DefaultFont->{"Courier-Bold",24.} ] ) (* first animation, secants only on a parabola *) opts = ( AnimationFunction -> (DisplayAnimation["secants1.anim",#]&) ) xlist = {-1,-.9,-.8,-.7,-.6,-.5,-.4,-.3,-.2,-.1,0,.1,.2,.3,.4,.45,.475, .525,.55,.6,.7,.8,.9,1} ShowAnimation[ Table[ SecantFrame[x^2,x,0.5,xlist[[i]],{{-1.2,1.2},{-0.2,1.2}}], {i,1,Length[xlist]}], opts] Print["-- wrote file secants1.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/secants1.", ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"] Table[ Display[writetofile[i], SecantFrame[x^2,x,0.5,xlist[[i]],{{-1.2,1.2},{-0.2,1.2}}]], {i,1,Length[xlist]}] Print["-- rasterized frames from secants1 --"] *) (* second animation, secants and tangent on the same parabola *) opts = ( AnimationFunction -> (DisplayAnimation["secants2.anim",#]&) ) xlist = {-1,-.9,-.8,-.7,-.6,-.5,-.4,-.3,-.2,-.1,0,.1,.2,.3,.4,.45,.475, .525,.55,.6,.7,.8,.9,1} ShowAnimation[ Table[ SecantTangentFrame[x^2,x,0.5,xlist[[i]],{{-1.2,1.2},{-0.2,1.2}}], {i,1,Length[xlist]}], opts] Print["-- wrote file secants2.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/secants2.", ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"] Table[ Display[writetofile[i], SecantTangentFrame[x^2,x,0.5,xlist[[i]],{{-1.2,1.2},{-0.2,1.2}}]], {i,1,Length[xlist]}] Print["-- rasterized frames from secants2 --"] *) (* third animation: a nondifferentiable function due to a corner *) opts = ( AnimationFunction -> (DisplayAnimation["secants3.anim",#]&) ) xlist = Join[Table[t, {t, .05, .55,.05}],{.57,.58,.59,.595,.605,.61,.62,.63}, Table[t,{t,.65,.95,.05}]] ShowAnimation[ Table[ SecantFrame[(1/4+Abs[x-3/5])(1-(x-1/2)^2),x,3/5, xlist[[i]],{{0,1}, {0,1}}], {i,1,Length[xlist]}], opts] Print["-- wrote file secants3.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/secants3.", ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"] Table[ Display[writetofile[i], SecantFrame[(1/4+Abs[x-3/5])(1-(x-1/2)^2),x,3/5, xlist[[i]],{{0,1}, {0,1}}]], {i,1,Length[xlist]}] Print["-- rasterized frames from secants3 --"] *) (* fourth animation: a nondifferentiable function due to a vertical tangent *) opts = ( AnimationFunction -> (DisplayAnimation["secants4.anim",#]&) ) xlist = Join[Table[t,{t,-2,-.2,.2}], {-.1,-.05,-.025,-.0125,-.00625,-.0001,.0001, .00625,.0125,.025,.05,.1},Table[t,{t,.2,2,.2}]] ShowAnimation[ Table[ SecantFrame[Sign[x]Abs[x]^(1/3),x,0,xlist[[i]],{{-2,2}, {-1.3,1.3}}], {i,1,Length[xlist]}], opts] Print["-- wrote file secants4.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/secants4.", ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"] Table[ Display[writetofile[i], SecantFrame[Sign[x]Abs[x]^(1/3),x,0,xlist[[i]],{{-2,2}, {-1.3,1.3}}]], {i,1,Length[xlist]}] Print["-- rasterized frames from secants4 --"] *) (* fifth animation: like the first but with parabola from bouncing ball demo *) opts = ( AnimationFunction -> (DisplayAnimation["secants5.anim",#]&) ) xlist = Join[Table[i,{i,0,14}],{15.0001},Table[i,{i,16,30}]]/60. ShowAnimation[ Table[ SecantFrame[100-400 x^2,x,0.25,xlist[[i]],{{0.,1.},{0.,120.}}], {i,1,Length[xlist]}], opts] Print["-- wrote file secants5.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/secants5.", ToString[PaddedForm[i,3,NumberPadding->{"0",""}]],".ppm"] Table[ Display[writetofile[i], SecantFrame[100-400 x^2,x,0.25,xlist[[i]],{{0.,1.},{0.,120.}}], {i,1,Length[xlist]}]], {i,1,Length[xlist]}] Print["-- rasterized frames from secants5 --"] *) End[] (* end of context private *) EndPackage[]