home *** CD-ROM | disk | FTP | other *** search
-
- (*:Version: Mathematica 2.0 *)
-
- (*:Name: Graphics`PlotField` *)
-
- (*:Title: Vector Field Plots of 2D Vector Functions *)
-
- (*:Author:
- Kevin McIsaac, Wolfram Research, Inc.
- Updated by Mike Chan and Bruce Sawhill, Wolfram Research, Inc.,
- September 1990
- Modified April, 1991, by John M. Novak
- *)
-
- (*:Keywords:
- vector field plot, 2D Vector Functions, Polya representation
- *)
-
- (*:Requirements: none. *)
-
- (*:Warnings: none. *)
-
- (*:Sources:
-
- *)
-
- (*:Summary: This package does plots of vector fields in the plane.
- You give the vector field as a pair of functions in the function
- PlotVectorField. If you give
- a scalar function, you can use PlotGradientField or
- PlotHamiltonianField to plot its gradient vector field or
- Hamiltonian vector field respectively.
- *)
-
- BeginPackage["Graphics`PlotField`",
- "Geometry`Rotations`",
- "Utilities`FilterOptions`"]
-
- PlotVectorField::usage =
- "PlotVectorField[f, {x, x0, x1, (xu)}, {y, y0, y1, (yu)}, (options)]
- produces a vector field plot of the two-dimensional vector function f.";
-
- PlotGradientField::usage = "PlotGradientField[f, {x, x0, x1, (xu)},
- {y, y0, y1, (yu)}, (options)] produces a vector field plot of the
- gradient vector field of the scalar function f by calculating its
- derivatives analytically.";
-
- PlotHamiltonianField::usage = "PlotHamiltonianField[f, {x, x0, x1,
- (xu)}, {y, y0, y1, (yu)}, (options)] produces a vector field plot
- of the Hamiltonian vector field of the scalar-valued function f by
- calculating its derivatives analytically.";
-
- PlotPolyaField::usage= "PlotPolyaField[f[x + I y], {x, x0, x1,
- (dx)}, {y, y0, y1, (dy)}, options] plots the function f in the
- complex plane using Polya representation.";
-
- ListPlotVectorField::usage = "ListPlotVectorField[{{vec11,vec12,..},...}]
- accepts a rectangular array of vectors (larger than 2x2) and displays
- them, with each vector positioned in the same location graphically
- as the matrix would be (ie, vector 1,1 in the upper right corner).
- ListPlotVectorField[{{pt,vec},{pt,vec},...] displays a list of
- vectors, each based at the corresponding point."
-
- ScaleFactor::usage=
- "ScaleFactor is an option for the PlotField functions that
- scales the vectors to a specified length. Default is Automatic;
- at this setting, those functions that use a coordinate grid
- (PlotVectorField, etc.) have the vectors scaled to this grid.
- This scaling is applied after ScaleFunction and MaxArrowLength.";
-
- ScaleFunction::usage=
- "ScaleFunction rescales each vector to a length determined by applying
- a pure function to the current length of that vector. It will ignore
- vectors of 0 magnitude. Note that because this is applied before the
- ScaleFactor, this is most useful for resizing the relative lengths of the
- vectors. This is also applied before MaxArrowLength."
-
- MaxArrowLength::usage=
- "MaxArrowLength is an option for the PlotField functions
- that determines the largest vector to be drawn. The
- value is compared to the magnitudes of all
- the vectors and causes all longer vectors to not be
- drawn. This is applied after the ScaleFunction but before the
- ScaleFactor. The initial setting is MaxArrowLength->None (no maximum).";
-
- ColorFunction::usage=
- "ColorFunction is an option for the PlotField functions that
- determines the color and style used to display the vectors. It
- is a pure function that accepts a value of 0 to 1; 0 corresponds
- to the shortest vector, 1 the longest.";
-
- Begin["`Private`"]
-
- rot45 = N[RotationMatrix2D[7Pi/8]];
- rotm45 = N[RotationMatrix2D[-7Pi/8]];
- vector[{x_, y_},{dx_,dy_},
- {{x0_,x1_},{y0_,y1_}}, ratio_] :=
- Block[{xr, yr, p1, p2, end, start,
- direction},
- xr = x1 - x0;
- yr = y1 - y0;
- start = {(x-x0)/xr,(y-y0)/yr}{1,ratio};
- end = {(x+dx-x0)/xr,(y+dy-y0)/yr}{1,ratio};
- direction = (end-start)/3;
- p1 = end + (rot45 . direction);
- p2 = end + (rotm45 . direction);
- If[NumberQ[dx] && NumberQ[dy],
- {Line[{Scaled[start], Scaled[end]}],
- Line[{Scaled[p1], Scaled[end],
- Scaled[p2]}]},
- (* else *)
- {PointSize[.015],Point[{x,y}]}
- ]
- ]
- automatic[x_, value_] :=
- If[x === Automatic, value, x]
-
- magnitude[v_List] := Sqrt[Plus @@ (v^2)]
-
- ListPlotVectorField::ragged =
- "ListPlotVectorField requires a rectangular array of vectors."
-
- Options[ListPlotVectorField] =
- {ScaleFactor->Automatic,
- ScaleFunction->None,
- MaxArrowLength->None,
- ColorFunction->None,
- AspectRatio->1};
-
- ListPlotVectorField[ vects:{{_?VectorQ,_?VectorQ}..}, opts___] :=
- Module[{maxsize,scale,scalefunct,colorfunct,points,
- vectors,colors,mags,scaledmag,allvecs,
- vecs = N[vects]},
- {maxsize,scale,scalefunct,colorfunct} =
- {MaxArrowLength,ScaleFactor,ScaleFunction,
- ColorFunction}/.{opts}/.Options[ListPlotVectorField];
-
- If[Not[NumberQ[N[maxsize]] && maxsize =!= None],
- maxsize = None,
- maxsize = N[maxsize]];
- If[Not[NumberQ[N[scale]]] &&
- scale =!= Automatic,
- scale = Automatic,
- scale = N[scale]];
-
- vecs = Cases[vecs,{_,_?(VectorQ[#,NumberQ]&)}];
- {points, vectors} = Transpose[vecs];
- mags = Map[magnitude,vectors];
- If[colorfunct == None, colorfunct = {}&];
- If[Max[mags - Min[mags]] == 0,
- colors = Map[colorfunct,Table[0,{Length[mags]}]],
- colors = Map[colorfunct,
- (mags - Min[mags])/Max[mags - Min[mags]]]
- ];
-
- If[scalefunct =!= None,
- scaledmag = (If[# == 0, 0, scalefunct[#]]&) /@ mags;
- vectors = MapThread[If[#2 == 0, {0,0}, #1 #2/#3]&,
- {vectors,scaledmag,mags}];
- mags = scaledmag
- ];
-
- allvecs = Transpose[{colors,points,vectors,mags}];
-
- If[maxsize =!= None,
- allvecs = Select[allvecs, (#[[4]]<=maxsize)&]
- ];
-
- scale = automatic[scale,Max[mags]]/Max[mags];
-
- allvecs = Map[{#[[1]],#[[2]],scale #[[3]]}&,
- allvecs];
-
- pr = PlotRange[ Graphics[
- Flatten[Apply[Line[{#2,#2+#3}]&,allvecs,{1}]]]];
- ratio = AspectRatio /.{opts}/.Options[PlotVectorField];
-
- Show[Graphics[
- Flatten[Apply[{#1,vector[#2,#3,pr,ratio]}&,
- allvecs,{1}]],
- PlotRange->pr,
- FilterOptions[Graphics, opts],
- AspectRatio -> ratio]]
-
- ]/; Last[Dimensions[vects]] == 2
-
-
- ListPlotVectorField[ vects:{{(_?VectorQ)..}..},opts___] :=
- Module[{dim = Dimensions[vects],flag = True,vecs = Reverse[vects]},
- flag = And @@ Map[SameQ[Dimensions[#],
- Dimensions[vecs[[1]]]]&, vecs];
- If[flag,
- ar = Array[{#2,#1}&,Evaluate[Take[dim,2]]];
- ar = Flatten[MapThread[List,{ar,vecs},2],1],
- Message[ListPlotVectorField::ragged]
- ];
- ListPlotVectorField[ar,opts]/;flag
- ]/; Last[Dimensions[vects]] == 2
-
- Options[PlotVectorField] =
- Join[Options[ListPlotVectorField],{PlotPoints->15}]
-
- SetAttributes[PlotVectorField, HoldFirst]
-
- PlotVectorField[f_, {u_, u0_, u1_, du_:Automatic},
- {v_, v0_, v1_, dv_:Automatic}, opts___] :=
- Module[{plotpoints,dua,dva,vecs},
- {plotpoints} = {PlotPoints}/.{opts}/.Options[PlotVectorField];
- dua = automatic[du,(u1 - u0)/(plotpoints-1)];
- dva = automatic[dv,(v1 - v0)/(plotpoints-1)];
- vecs = Flatten[Table[{N[{u,v}],N[f]},
- Evaluate[{u,u0,u1,dua}],Evaluate[{v,v0,v1,dva}]],1];
- ListPlotVectorField[vecs,
- FilterOptions[ListPlotVectorField,opts],
- FilterOptions[Graphics,opts],
- ScaleFactor->N[Min[dua,dva]]]
- ]
-
- PlotGradientField[function_,
- {u_, u0__},
- {v_, v0__},
- options___] :=
- PlotVectorField[Evaluate[{D[function, u], D[function, v]}],
- {u, u0},
- {v, v0},
- options]
-
- PlotHamiltonianField[function_,
- {u_, u0__},
- {v_, v0__},
- options___] :=
- PlotVectorField[Evaluate[{D[function, v], -D[function, u]}],
- {u, u0},
- {v, v0},
- options]
-
-
- SetAttributes[PlotPolyaField, HoldFirst]
- PlotPolyaField[f_, x_List, y_List, opts___] :=
- PlotVectorField[{Re[#], -Im[#]} & @ f, x, y, opts,
- ScaleFunction->(Log[#+1]&)]
-
- End[] (* Graphics`PlotField`Private` *)
-
- EndPackage[] (* Graphics`PlotField` *)
-
- (*:Limitations: none known. *)
-
-
- (*:Examples:
-
- PlotVectorField[ {Sin[x],Cos[y]},{x,0,Pi},{y,0,Pi}]
-
- PlotVectorField[ { Sin[x y], Cos[x y] },{x,0,Pi},{y,0,Pi}]
-
- PlotGradientField[ x^3 + y^4,{x,0,10},{y,0,10}]
-
- PlotPolyaField[ (x+I y)^4,{x,5,10},{y,5,10}]
-
-
- *)
-
-
-
-
-
-
-
-