(*   This is the file complexcurves.m, written by

     Douglas N. Arnold  <dna@math.psu.edu>
     Department of Mathematics
     Penn State
     University Park, PA  16802
     
     January 1997
*)
      
(* This package defines an object specifying a curve in the complex
   plane (curve[f[t],{t,a,b},options...]), an operator image to compose
   such a curve with a complex function to obtain a new curve, an
   operator showcurve to display a curve or list of curves, and a
   variety of useful curves and curve families.  See the usage message
   for more details.
   
   Example of usage: show the image of a square of radius four centered
   at the orgin under the complex exponential map:
   
   showcurve[image[Exp,
     linearray[-2-2 I,2+2 I,6,11,PlotStyle->{{Thickness[.008]}}]],
     PlotRange->All,Background->GrayLevel[0],DefaultColor->RGBColor[1,1,0],
     AspectRatio->Automatic]
   
   Douglas N. Arnold, dna@math.psu.edu, 1/1997
*)

BeginPackage["complexcurves`"]

curve::usage =
"A curve in the complex plane is specified as curve[f[t],{t,a,b},options...]
where f is a complex-valued function of one real variable and the
options are the same as those for ParametricPlot.  See all showcurve."

image::usage =
"If g is a complex-valued function of one complex variable,
and c is a curve in the complex plane (specified as
curve[f[t],{t,a,b},options...]), then image[g,c] is the image of the
curve c under the mapping g.  See all curve."

showcurve::usage =
"If c is a curve in the complex plane (specified as
curve[f[t],{t,a,b},options...]), or a list of such curves, then
showcurve[c,options...] displays the curve.  The options to showcurve
are the same as those to Show.  See also curve."

line::usage =
"line[z1,z2,options...] is a curve in the complex plane, namely the line
segment connecting the given complex points.  See also curve."

pline::usage =
"pline[{z1,z2,...,zn},options...] is a curve in the complex plane, namely
the broken line segment connecting the given complex points.  See also curve."

rectangle::usage =
"rectangle[z1,z2,options...] is a closed curve in the complex plane, namely
the rectangle aligned with the axes and having the given corners.  See
also pline."

hlinearray::usage =
"hlinearray[z1,z2,nlines,options...] is a list of nlines curves in the
complex plane, namely equally spaced horizontal lines placed over a
rectangular region with the given points as corners.  See also line."
    
vlinearray::usage =
"vlinearray[z1,z2,nlines,options...] is a list of nlines curves in the
complex plane, namely equally spaced vertical lines placed over a
rectangular region with the given points as corners.  See also line."
    
linearray::usage =
"linearray[z1,z2,hlines,vlines,options...] is the union of the
hlinearray[z1,z2,hlines,options] and vlinearray[z1,z2,vlines,options].
See also hlinearray, vlinearray."
  
circle::usage =
"circle[center,radius,arg0,arg1,options...] is a curve in the complex
plane, namely the circular arc with the given center (a complex number)
and radius and argument interval.  See also curve."
    
circlearray::usage =
"circlearray[center,r0,r1,arg0,arg1,ncircles,options...] is a list of
ncircles curves in the complex plane, namely concentric circular arcs
with the given center and argument range and with radii varying linearly
from r0 to r1.  See also circle."
  
spoke::usage =
"spoke[center,r0,r1,arg,options...] is a curve in the complex plane,
namely the radial line segment with the given center, radius range, and
argument.  See also curve."
    
spokearray::usage =
"spokearray[center,r0,r1,arg0,arg1,nspokes,options...] is a list of
nspokes curves in the complex plane, namely spokes with a common center
and radius range, and with linearly varying argument.  See also spokes."

polararray::usage =
"polararray[center,r0,r1,arg0,arg1,ncircles,nspokes,options...] is the union of
circlearray[center,r0,r1,arg0,arg1,ncircles,options] and
spokearray[center,r0,r1,arg0,arg1,nspokes,options].  See also
circlearray and spokearray."

Begin["`private`"]

Format[curve[___]] = "-complex curve-";

(* curvegraphic is a Graphic object depicting a curve or curves.  This
   is a private function in this package. *)
   
curvegraphic[curve[func_,other___]]:=ParametricPlot[{Re[func],Im[func]},other,DisplayFunction->Identity]

SetAttributes[curvegraphic,Listable]

showcurve[curvelist_,opts___]:=
 Show[curvegraphic[curvelist],opts,DisplayFunction->$DisplayFunction]

image[f_,curve[func_,other___]] := curve[f[func],other]

SetAttributes[image,Listable]

line[z1_,z2_,opts___] := curve[(1-t)z1+t z2,{t,0,1},opts]

pline[z_,opts___] :=
  curve[Which@@Join@@
          Table[{((j-1)/(Length[z]-1) <= t && t <= j/(Length[z]-1)),
                 z[[j]]+((Length[z]-1)t-(j-1))(z[[j+1]]-z[[j]])},
                  {j,1,Length[z]-1}], {t,0,1},opts]

rectangle[z1_,z2_,opts___] :=
  pline[{z1,Re[z2]+I Im[z1],z2,Re[z1]+I Im[z2],z1},opts]

vlinearray[z1_,z2_,lines_,opts___] :=
  Table[line[Re[z1]+j(Re[z2]-Re[z1])/(lines-1)+I Im[z1],
             Re[z1]+j(Re[z2]-Re[z1])/(lines-1)+I Im[z2],
       opts], {j,0,lines-1}]

hlinearray[z1_,z2_,lines_,opts___] :=
  Table[line[Re[z1]+I (Im[z1]+j(Im[z2]-Im[z1])/(lines-1)),
             Re[z2]+I (Im[z1]+j(Im[z2]-Im[z1])/(lines-1)),
       opts], {j,0,lines-1}]

linearray[z1_,z2_,hlines_,vlines_,opts___] :=
  Join[hlinearray[z1,z2,hlines,opts],vlinearray[z1,z2,vlines,opts]]

circle[center_,radius_,arg0_,arg1_,opts___] :=
  curve[center+radius Exp[I t],{t,arg0,arg1},opts]

circlearray[center_,r0_,r1_,arg0_,arg1_,circles_,opts___] :=
  Table[circle[center,r0+j(r1-r0)/(circles-1),arg0,arg1,opts], {j,0,circles-1}]

spoke[center_,r0_,r1_,arg_,opts___] := 
  line[center+r0 Exp[I arg],center+r1 Exp[I arg],opts]

spokearray[center_,r0_,r1_,arg0_,arg1_,spokes_,opts___] :=
  Table[spoke[center,r0,r1,arg0+j(arg1-arg0)/(spokes-1),opts],
   {j,0,spokes-1}]

polararray[center_,r0_,r1_,arg0_,arg1_,circles_,spokes_,opts___] :=
   Join[circlearray[center,r0,r1,arg0,arg1,circles,opts],
        spokearray[center,r0,r1,arg0,arg1,spokes,opts]]

End[]
EndPackage[]
