INTERFACE SPPlot; IMPORT SPTriang, PSPlot, HLR3, LR3; TYPE LONG = LONGREAL; BOOL = BOOLEAN; Coords = SPTriang.Coords; File = PSPlot.File; PMap = HLR3.PMap; SIGN =[-1..1]; PROCEDURE Open(name: TEXT; eps: BOOLEAN): File; (* Opens a Postscript file "name.ps" or "name.eps" for plotting spherical functions. In either case the file will contain a single drawing. Be sure to call Close below after the plot is done. The the actual size of the drawing will be 15 by 15 cm. The default plotting coordinate range (after perspective projection) is be "[-1.2 .. +1.2]" *) PROCEDURE Close(f: File); (* Terminates any plots written to "file", and closes it. *) PROCEDURE Sphere(f: File); (* Draws the outline of the unit sphere. Be sure to call "f.setFillColor" and/or "f.setLineColor" as appropriate. Note that IsoLines also paints the surface of the sphere, so if you are going to call IsoLines with a visible fill color, you should do "f.setFillColor(PSPlot.Invisible)" before calling Sphere, and vice-versa. *) PROCEDURE PerspMap(READONLY obs, upp: HLR3.Point): PMap; (* Computes a perspective projection matrix for spherical painting, as seen from point "obs" (which must be well outside the unit sphere). Use the result as the "map" parameter for the plotting procedures below. The `virtual camera' is rotated in such a way that the point "upp" will project on the image's vertical axis. *) PROCEDURE Axis( f: File; READONLY map: PMap; dir: LR3.T; length: LONG; sense: SIGN := 0; ); (* Draws an arrow from the origin, with the specified length and direction. If "sense" is -1, draws the arrow only if it pierces the invisible part of the sphere; if "sense" = +1, draws it only if it pierces the visible part; if "sense" is 0 (default), always draws the arrow. *) PROCEDURE CoordAxes( f: File; READONLY map: PMap; sense: SIGN; ); (* Draws the three Cartesian coordinate axes X, Y, Z. The "sense" parameter is passed to "Axis". *) PROCEDURE Segment( f: File; READONLY map: PMap; p, q: Coords; N: CARDINAL := 20; ); (* Draws segment from "p" to "q", dividing it into "N" pieces. *) PROCEDURE Triangulation( f: File; READONLY map: PMap; READONLY tri: SPTriang.T; N: CARDINAL := 20; ); (* Draws all edges of the spherical triangulation "tri", using "N" steps along each edge. *) TYPE ScalarField = PROCEDURE (READONLY p: Coords): LONG; PROCEDURE Isolines( f: File; READONLY map: PMap; (* Perspective projection matrix. *) func: ScalarField; (* Function to plot. *) M, N: CARDINAL; (* Grid size. *) fStep: REAL; (* Isoline spacing. *) fStart: REAL := 0.0; (* First isoline level. *) sign: SIGN; (* Which part to plot (neg,all,pos).*) ); (* Plots the isolines of the spherical function "func". *) PROCEDURE PaintValues( f: File; READONLY map: PMap; (* Perspective projection matrix. *) func: ScalarField; (* Function to plot. *) M, N: CARDINAL; (* Grid size. *) fMin: LONG; (* Minimum function value. *) cMin: PSPlot.Color; (* Color to use for "fMin". *) clipMin: BOOLEAN; (* TRUE omits parts below "fMin". *) fMax: LONG; (* Maximum function VALUE. *) cMax: PSPlot.Color; (* Color to use for "fMax". *) clipMax: BOOLEAN; (* TRUE omits parts above "fMax". *) dLight: LR3.T; (* Direction towards main light source. *) shadow: REAL := 0.1; (* Amount of darkening by shadow. *) ); (* Plots the values of the spherical function "func" as color gradations. Values between "fMin" and "fMax" are mapped to colors between "cMin" and "cMax", by linear interpolation. Values below "fMin" are either left blank ("clipMin = TRUE") or painted with "cMin" ("clipMin = FALSE"). Values above "fMax" are handled in the same way, depending on "clipMax". Parts of the sphere away from the direction "dLight" are darkened slightly, and parts facing towards it are lightened. The "shadow" parameter specifies the maximum relative change in the color's intensity, in either sense. *) TYPE VectorField = PROCEDURE (READONLY p: Coords): LR3.T; PROCEDURE Vectors( f: File; READONLY map: PMap; (* Perspective projection matrix. *) fld: VectorField; (* Vector field defined on the sphere. *) N: CARDINAL; (* Grid size. *) scale: LONG; (* Scale factor for vector field. *) ); (* Plots the vector field "fld", sampled at points on the sphere. Each sample vector "v" is drawn as a dot with a whisker "scale*abs(v)" long (in world coordinates). *) PROCEDURE Everything( func: ScalarField; (* The function to plot *) tri: REF SPTriang.T; (* Triangulation to draw, or NIL *) fMax: LONG; (* Nominal maximum absolute function value *) fStep: REAL; (* Isoline spacing. *) M, N: CARDINAL; (* Grid size. *) obs: HLR3.Point; (* Observer's position *) upp: HLR3.Point; (* Camera vertical reference *) dLight: LR3.T; (* Direction towards main light source. *) outName: TEXT; (* Output file name, minus extension *) eps: BOOL; (* TRUE for Encapsulated Postscript (".eps") format *) verbose: BOOL := TRUE; (* TRUE to print messages along the way. *) ); (* Plots everything about the function "func": sphere, triangulation (if not NIL), values, and isolines. *) PROCEDURE BothSides( func: ScalarField; (* The function to plot. *) tri: REF SPTriang.T; (* Triangulation to draw, or NIL *) fMax: LONG; (* Nominal MAX(ABS(fun)), or 0 to compute it. *) fStep: REAL; (* Isoline spacing. *) M, N: CARDINAL; (* Grid size. *) obs: HLR3.Point; (* Observer's position *) upp: HLR3.Point; (* Camera vertical reference *) dLight: LR3.T; (* Direction towards main light source. *) outName: TEXT; (* Output file name, minus extension *) eps: BOOL; (* TRUE for Encapsulated Postscript (".eps") format *) verbose: BOOL := TRUE; (* TRUE to print messages along the way. *) ); (* Plots two views of the the function "func", front and back, with "Everything". If "fMax" is non-zero, uses it as the plotting range for function values; else uses the actual "MAX(ABS(func))" (estimated over a large set of sample points), rounded to a nice number. *) PROCEDURE RoundMax(x: LONG): LONG; (* Rounds the number "x", which must be positive, to a nice value (namely 0.25, 0.50, or 1.00 times a power of 10). *) END SPPlot.