384 lines
15 KiB
Plaintext
384 lines
15 KiB
Plaintext
|
_MAKING THE MOVE TO MODULA-2_
|
|||
|
by J.V. Auping and Chis Johnston
|
|||
|
|
|||
|
[LISTING ONE]
|
|||
|
|
|||
|
DEFINITION MODULE ModPlot;
|
|||
|
|
|||
|
(* Title : High level Modula-2 Graphics library interface
|
|||
|
Author : Judy Auping
|
|||
|
System : PC Graphics
|
|||
|
Compiler: LOGITECH MODULA-2/86
|
|||
|
*)
|
|||
|
|
|||
|
FROM DataDefs IMPORT
|
|||
|
DeviceType,UnitsType,SizeType,AngleType,LineType,ColorType,
|
|||
|
FontType,OriginType,SymbolType,ModeType,STRING80;
|
|||
|
|
|||
|
EXPORT QUALIFIED
|
|||
|
GraphInit,SetPlotDevice,SetPlotArea,SetScaledArea,SetScale,SetUnits,
|
|||
|
SetCharSize,SetLabelAngle,SetLineType,SetPenColor,SetBackgroundColor,
|
|||
|
SetLabelOrigin,SetFixedDigits,ReturnRatio,SetFontType,
|
|||
|
Draw,Move,IncDraw,IncMove,DrawXAxis,DrawYAxis,DrawAxes,DrawGrid,
|
|||
|
DrawLabel,DrawLabelledAxes,DrawLabelledGrid,DrawFrame,DrawSymbol,
|
|||
|
Where,NewScreen,CloseGraphics;
|
|||
|
|
|||
|
PROCEDURE GraphInit;
|
|||
|
(* Initializes system-MUST be called before any output generated *)
|
|||
|
PROCEDURE SetPlotDevice(GraphDevice: DeviceType);
|
|||
|
(* Selects output device for subsequent graphics commands *)
|
|||
|
PROCEDURE SetPlotArea(XMin,XMax,YMin,YMax: REAL);
|
|||
|
(* Sets the 'clip' area in % of absolute device boundaries*)
|
|||
|
PROCEDURE SetScaledArea(XMin,XMax,YMin,YMax: REAL);
|
|||
|
(* Sets the area in % of absolute device boundaries to which
|
|||
|
subsequent SetScale takes effect*)
|
|||
|
PROCEDURE SetScale(XMin,XMax,YMin,YMax: REAL);
|
|||
|
(* Sets the user scale *)
|
|||
|
PROCEDURE SetUnits(GraphUnits: UnitsType);
|
|||
|
(* Sets either User (Scaled units) or Device (absolute units) *)
|
|||
|
PROCEDURE SetCharSize(CharSize: SizeType);
|
|||
|
(* Sets character size for subsequent labels *)
|
|||
|
PROCEDURE SetLabelAngle(LabelRotation: AngleType);
|
|||
|
(* Sets the angle of rotation of subseqent labels *)
|
|||
|
PROCEDURE SetLineType(LineTypeSelected: LineType);
|
|||
|
(* Sets the line type for subsequent Draw commands *)
|
|||
|
PROCEDURE SetPenColor(PenColor: ColorType);
|
|||
|
(* Sets the pen color for subsequent output *)
|
|||
|
PROCEDURE SetBackgroundColor(BackgroundColor: ColorType);
|
|||
|
(* Sets the background color (screen only) *)
|
|||
|
PROCEDURE SetLabelOrigin(LabelOrigin: OriginType);
|
|||
|
(* Determines orientation relative to current position with
|
|||
|
which subsequent labels will be drawn *)
|
|||
|
PROCEDURE SetFixedDigits(XNumDigits,YNumDigits: CARDINAL);
|
|||
|
(* Sets number of digits to right of decimal point for
|
|||
|
subsequent DrawLabelledAxes or DrawLabelledGrid *)
|
|||
|
PROCEDURE ReturnRatio(): REAL;
|
|||
|
(* Returns the ratio of the physical dimensions of the
|
|||
|
plotting area of the current device *)
|
|||
|
PROCEDURE SetFontType(FontTypeSelected: FontType);
|
|||
|
(* Sets the font type for subsequent label commands *)
|
|||
|
PROCEDURE Draw(XCoord,YCoord: REAL);
|
|||
|
(* Draw a line from the active position to the specified coords *)
|
|||
|
PROCEDURE Move(XCoord,YCoord: REAL);
|
|||
|
(* Move the active position to the specified coordinates *)
|
|||
|
PROCEDURE IncDraw(XIncr,YIncr: REAL);
|
|||
|
(* Do an incremental draw from the active position *)
|
|||
|
PROCEDURE IncMove(XIncr,YIncr: REAL);
|
|||
|
(* Do an incremental move to the new active position *)
|
|||
|
|
|||
|
(* In the following set of axis drawing and labelling procedures,
|
|||
|
the variables XIntercept, YIntercept, XTicSpacing, YTicSpacing
|
|||
|
XMin, XMax, YMin, and YMax are all interpreted according to the
|
|||
|
most recent SetUnits, SetScaledArea, and Set Scale commands.
|
|||
|
MajorCount is an integer that specifies the number of tic intervals
|
|||
|
between major tic marks. In DrawLabelledAxes and DrawLabelledGrid,
|
|||
|
if MajorCount is positive, tic marks are drawn perpendicular to the
|
|||
|
corresponding axis; if negative, tic marks are parallel.
|
|||
|
MajorTicFrac specifies the size of the major tics as a percentage
|
|||
|
of the length of the corresponding axis.*)
|
|||
|
|
|||
|
PROCEDURE DrawXAxis(YIntercept,TicSpacing,XMin,XMax: REAL;
|
|||
|
MajorCount: INTEGER;
|
|||
|
MajorTicFrac: REAL);
|
|||
|
(* Draw an X-axis from XMin to XMax at the specified y-intercept*)
|
|||
|
PROCEDURE DrawYAxis(XIntercept,TicSpacing,YMin,YMas: REAL;
|
|||
|
MajorCount: INTEGER;
|
|||
|
MajorTicFrac: REAL);
|
|||
|
(* Draw a Y-axis from YMin to YMax at the specified x-intercept*)
|
|||
|
PROCEDURE DrawAxes(XIntercept,YIntercept,XTicSpacing,YTicSpacing: REAL;
|
|||
|
XMajorCount,YMajorCount: INTEGER;
|
|||
|
XMajorTicFrac,YMajorTicFrac: REAL);
|
|||
|
(* Draws full-scale axes intersecting at XIntercept and YIntercept*)
|
|||
|
PROCEDURE DrawGrid(XIntercept,YIntercept,XTicSpacing,YTicSpacing: REAL;
|
|||
|
XMajorCount,YMajorCount: INTEGER;
|
|||
|
XMinorTicFrac,YMinorTicFrac: REAL);
|
|||
|
(* Draws a full-scale grid, with lines spaced symmetrically
|
|||
|
around XIntercept,YIntercept *)
|
|||
|
PROCEDURE DrawLabel(LabelString: ARRAY OF CHAR);
|
|||
|
(* Writes LabelString at the current active position according
|
|||
|
to the current CharSize, LabelOrigin, and LabelRotation settings*)
|
|||
|
PROCEDURE DrawLabelledAxes(XIntercept,YIntercept,XTicSpacing,
|
|||
|
YTicSpacing: REAL;
|
|||
|
XMajorCount,YMajorCount: INTEGER;
|
|||
|
XMajorTicFrac,YMajorTicFrac: REAL);
|
|||
|
(* Draws a pair of axes in the same manner as DrawAxes. Puts
|
|||
|
labels at the major tic marks according to the current
|
|||
|
CharSize, XNumDigits, and YNumDigits settings *)
|
|||
|
PROCEDURE DrawLabelledGrid(XIntercept,YIntercept,XTicSpacing,
|
|||
|
YTicSpacing: REAL;
|
|||
|
XGridSpacing,YGridSpacing: INTEGER;
|
|||
|
XMajorTicFrac,YMajorTicFrac: REAL);
|
|||
|
(* Draws a full-scale grid as in DrawGrid and labels the grid
|
|||
|
lines as in DrawLabelledAxes *)
|
|||
|
PROCEDURE DrawFrame;
|
|||
|
(* Draws a box around the current plotting area *)
|
|||
|
PROCEDURE DrawSymbol(XCoord,YCoord: REAL;
|
|||
|
Symbol: SymbolType;
|
|||
|
Size: REAL);
|
|||
|
(* Draws the indicated symbol centered at XCoord,YCoord.
|
|||
|
Size is specified in mm *)
|
|||
|
PROCEDURE Where(VAR XCoord,YCoord: REAL);
|
|||
|
(* Returns the coordinate values of the current active position*)
|
|||
|
PROCEDURE NewScreen(Mode: ModeType);
|
|||
|
(* Clears the screen and sets the mode. No cursor in Menu mode*)
|
|||
|
PROCEDURE CloseGraphics;
|
|||
|
(* Cleans up the interrupts and restores to normal *)
|
|||
|
END ModPlot.
|
|||
|
|
|||
|
|
|||
|
[LISTING TWO]
|
|||
|
|
|||
|
DEFINITION MODULE GDriver;
|
|||
|
(* Title : Low Level CRT and Plotter Draw module
|
|||
|
Author : Chris Johnston
|
|||
|
System : Modula-2 Plotting System
|
|||
|
Compiler: LOGITECH MODULA-2/86
|
|||
|
*)
|
|||
|
|
|||
|
FROM DataDefs IMPORT ModeType, STRING80, DevPresentType;
|
|||
|
|
|||
|
EXPORT QUALIFIED
|
|||
|
ReadDevices, DrawAbs, MoveAbs, DrawString, SetMode, CleanUp;
|
|||
|
|
|||
|
PROCEDURE ReadDevices(VAR DevicesPresent : DevPresentType);
|
|||
|
(* Finds out what devices are available: EGA/CGA and
|
|||
|
IBM7372A/IBM7372B/IBM7371. An HP 7470 is reported
|
|||
|
as an IBM7371 and the HP 7475 is reported as an
|
|||
|
IBM7372A or B depending upon the paper size selected *)
|
|||
|
|
|||
|
PROCEDURE DrawAbs(XCoord, YCoord : CARDINAL);
|
|||
|
(* Draw a line from the current location to XCoord, YCoord
|
|||
|
on the selected device. Line type and color read from system
|
|||
|
globals *)
|
|||
|
|
|||
|
PROCEDURE MoveAbs(XCoord, YCoord : CARDINAL);
|
|||
|
(* Move from the current location to XCoord, YCoord on the
|
|||
|
selected device with the pen raised. *)
|
|||
|
|
|||
|
PROCEDURE DrawString(XCoord, YCoord : CARDINAL;
|
|||
|
LabelString : ARRAY OF CHAR);
|
|||
|
(* Draw the character string LabelString starting at XCoord, YCoord.
|
|||
|
The font, color, size, and rotation are selected from system globals
|
|||
|
*)
|
|||
|
|
|||
|
PROCEDURE SetMode( Mode : ModeType);
|
|||
|
(* Set the mode to text or graphics and clear the screen. This call has
|
|||
|
** NO EFFECT ** if the selected device is a plotter *)
|
|||
|
|
|||
|
PROCEDURE CleanUp;
|
|||
|
(* clean up the interrupt drivers and the character set at the end. *)
|
|||
|
|
|||
|
END GDriver.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
[LISTING THREE]
|
|||
|
|
|||
|
DEFINITION MODULE DataDefs;
|
|||
|
|
|||
|
(* Title : Data Definitions
|
|||
|
Author : Judy Auping
|
|||
|
System : PC Graphics
|
|||
|
Compiler: LOGITECH MODULA-2/86
|
|||
|
*)
|
|||
|
|
|||
|
EXPORT QUALIFIED
|
|||
|
DeviceType,UnitsType,SizeType,AngleType,LineType,ColorType,
|
|||
|
FontType,OriginType,SymbolType,DevPresentType,ModeType,STRING80,
|
|||
|
GraphDevice,LineTypeSelected,CharSize,FontTypeSelected,
|
|||
|
PenColor,BackgroundColor,LabelRotation,DeviceXMax,DeviceYMax,
|
|||
|
ErrorString, DriverError;
|
|||
|
|
|||
|
TYPE
|
|||
|
DeviceType = (EGA,CGA,IBM7372A,IBM7372B,IBM7371);
|
|||
|
UnitsType = (User,Device);
|
|||
|
SizeType = (Small,Med,Large,XLarge);
|
|||
|
AngleType = (Deg0,Deg45,Deg90,Deg135,Deg180,Deg225,Deg270,Deg315);
|
|||
|
LineType = (Solid, EndPoint, Dotted, ShortDash, LongDash);
|
|||
|
ColorType = (Black,Blue,Green,Cyan,Red,Magenta,Brown,White,
|
|||
|
DarkGray,LightBlue,LightGreen,LightCyan,
|
|||
|
LightRed,LightMagenta,Yellow,IntensifiedWhite);
|
|||
|
FontType = (Standard,Italic);
|
|||
|
OriginType = (UpperRight,CenterRight,LowerRight,UpperMiddle,
|
|||
|
CenterMiddle,LowerMiddle,UpperLeft,CenterLeft,
|
|||
|
LowerLeft);
|
|||
|
SymbolType = (Circle,Square,Triangle,Asterisk,Cross,Plus);
|
|||
|
DevPresentType = ARRAY DeviceType OF BOOLEAN;
|
|||
|
ModeType = (Graphics,Text,Menu);
|
|||
|
STRING80 = ARRAY[0..79] OF CHAR;
|
|||
|
|
|||
|
VAR
|
|||
|
GraphDevice: DeviceType;
|
|||
|
LineTypeSelected: LineType;
|
|||
|
CharSize: SizeType;
|
|||
|
FontTypeSelected: FontType;
|
|||
|
PenColor: ColorType;
|
|||
|
BackgroundColor: ColorType;
|
|||
|
LabelRotation: AngleType;
|
|||
|
DeviceXMax,DeviceYMax: CARDINAL;
|
|||
|
DriverError: BOOLEAN;
|
|||
|
ErrorString: STRING80;
|
|||
|
|
|||
|
END DataDefs.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
[LISTING FOUR]
|
|||
|
|
|||
|
MODULE Example;
|
|||
|
(* Title: Example of using the ModPlot graphics library
|
|||
|
Author: Judy Auping
|
|||
|
System: PC Graphics
|
|||
|
*)
|
|||
|
|
|||
|
FROM DataDefs IMPORT
|
|||
|
DeviceType,SizeType,ColorType,OriginType;
|
|||
|
|
|||
|
FROM ModPlot IMPORT
|
|||
|
GraphInit,SetPlotArea,SetScaledArea,SetScale,DrawAxes,SetPenColor,
|
|||
|
Move,Draw,DrawFrame,NewScreen,CloseGraphics,SetLabelOrigin,DrawLabel,
|
|||
|
SetCharSize,IncDraw,SetPlotDevice;
|
|||
|
|
|||
|
FROM MathLib0 IMPORT sin;
|
|||
|
|
|||
|
FROM InOut IMPORT Read,WriteString,WriteLn;
|
|||
|
|
|||
|
TYPE
|
|||
|
CornerType = (UpLeft,UpRight,LowLeft,LowRight);
|
|||
|
|
|||
|
CONST
|
|||
|
NPnts = 1000; pi = 3.14159;
|
|||
|
|
|||
|
VAR
|
|||
|
XValue: ARRAY[1..NPnts] OF REAL;
|
|||
|
YValue: ARRAY [UpLeft..LowRight] OF ARRAY[1..NPnts] OF REAL;
|
|||
|
NumTerms: ARRAY[UpLeft..LowRight] OF CARDINAL;
|
|||
|
IPlot: CornerType;
|
|||
|
IPnt,ITerm: CARDINAL;
|
|||
|
x,NextTerm: REAL;
|
|||
|
Input: CHAR;
|
|||
|
|
|||
|
PROCEDURE GeneratePlotArrays;
|
|||
|
(* This procedure generates arrays of data points for the Fourier series
|
|||
|
approximation of a sawtooth wave, where
|
|||
|
|
|||
|
y = 2 (sin x - sin(2x)/2 + sin(3x)/3 - sin(4x)/4 + ... )
|
|||
|
|
|||
|
The XValue array contains the x values for the plot in units of pi, where
|
|||
|
the values vary from zero to 4pi.
|
|||
|
|
|||
|
The YValue array of arrays contains four arrays of y values for
|
|||
|
different numbers of terms in the summation approximation. *)
|
|||
|
|
|||
|
BEGIN
|
|||
|
WriteString("Generating approximation functions"); (* Inform user *)
|
|||
|
NumTerms[UpLeft] := 5; NumTerms[UpRight] := 10;
|
|||
|
NumTerms[LowLeft] := 20; NumTerms[LowRight] := 100;
|
|||
|
|
|||
|
FOR IPnt := 1 TO NPnts DO
|
|||
|
|
|||
|
IF (IPnt MOD 100)=0 THEN
|
|||
|
WriteString(" ."); (* Let the user know the progress of *)
|
|||
|
END (* if *); (* the calculations.*)
|
|||
|
|
|||
|
FOR IPlot := UpLeft TO LowRight DO
|
|||
|
YValue[IPlot,IPnt] := 0.0; (* Initialize the terms. *)
|
|||
|
END (* for *);
|
|||
|
|
|||
|
x := FLOAT(IPnt) * (4.0 * pi)/FLOAT(NPnts);
|
|||
|
XValue[IPnt] := x/pi;
|
|||
|
|
|||
|
FOR ITerm := 1 TO NumTerms[LowRight] DO
|
|||
|
IF (ITerm MOD 2)=0 THEN (* even terms are negative *)
|
|||
|
NextTerm := -2.0 * sin(FLOAT(ITerm)* x)/FLOAT(ITerm);
|
|||
|
ELSE (* odd terms are positive,*)
|
|||
|
NextTerm := 2.0 * sin(FLOAT(ITerm)* x)/FLOAT(ITerm);
|
|||
|
END (* if *);
|
|||
|
|
|||
|
FOR IPlot := UpLeft TO LowRight DO
|
|||
|
IF ITerm<=NumTerms[IPlot] THEN
|
|||
|
YValue[IPlot,IPnt] := YValue[IPlot,IPnt] + NextTerm;
|
|||
|
END (* if *);
|
|||
|
END (* for *);
|
|||
|
END (* for *);
|
|||
|
END (* for *);
|
|||
|
END GeneratePlotArrays;
|
|||
|
|
|||
|
BEGIN
|
|||
|
GeneratePlotArrays;
|
|||
|
GraphInit;
|
|||
|
SetPlotDevice(IBM7372A);
|
|||
|
WriteLn; WriteString("Drawing plot . . ."); (*Let user know where we are*)
|
|||
|
|
|||
|
FOR IPlot := UpLeft TO LowRight DO (*Draw a plot for each array*)
|
|||
|
CASE IPlot OF (* For each array, choose the appropriate plotting area*)
|
|||
|
UpLeft:SetPlotArea(0.0,45.0,60.0,100.0); (*Upper left corner *)
|
|||
|
SetScaledArea(5.0,40.0,62.0,94.0);
|
|||
|
|UpRight: SetPlotArea(55.0,100.0,60.0,100.0); (*Upper right corner*)
|
|||
|
SetScaledArea(60.0,95.0,62.0,94.0);
|
|||
|
|LowLeft:SetPlotArea(0.0,45.0,0.0,40.0); (*Lower left*)
|
|||
|
SetScaledArea(5.0,40.0,2.0,34.0);
|
|||
|
|LowRight:SetPlotArea(55.0,100.0,0.0,40.0); (*Lower right*)
|
|||
|
SetScaledArea(60.0,95.0,2.0,34.0);
|
|||
|
END (* case *);
|
|||
|
|
|||
|
SetScale(0.0,4.0,-4.0,4.0); (* remember, x is in units of pi *)
|
|||
|
SetPenColor(Black);
|
|||
|
DrawAxes(0.0,0.0,1.0,1.0,2,2,3.0,2.0); (* draw axes without labels *)
|
|||
|
(* Labels are drawn separately so we can put 'pi' on x-axis labels*)
|
|||
|
SetCharSize(Small); (* Label the axes *)
|
|||
|
SetLabelOrigin(CenterLeft); (* First, the y-axis *)
|
|||
|
Move(-0.05,4.0); DrawLabel("4");
|
|||
|
Move(-0.05,2.0); DrawLabel("2");
|
|||
|
Move(-0.05,0.0); DrawLabel("0");
|
|||
|
Move(-0.05,-2.0); DrawLabel("-2");
|
|||
|
Move(-0.05,-4.0); DrawLabel("-4");
|
|||
|
|
|||
|
SetLabelOrigin(LowerMiddle); (* Then the x-axis *)
|
|||
|
Move(2.0,-0.5); DrawLabel("2pi");
|
|||
|
Move(4.0,-0.5); DrawLabel("4pi");
|
|||
|
|
|||
|
CASE IPlot OF (*Set a new pen color for each plot *)
|
|||
|
UpLeft: SetPenColor(Red);
|
|||
|
|UpRight: SetPenColor(Green);
|
|||
|
|LowLeft: SetPenColor(Blue);
|
|||
|
|LowRight: SetPenColor(Magenta);
|
|||
|
END (* case *);
|
|||
|
|
|||
|
Move(0.0,0.0); (* Start at the origin *)
|
|||
|
FOR IPnt := 1 TO NPnts DO
|
|||
|
Draw(XValue[IPnt],YValue[IPlot,IPnt]); (*Draw to each point*)
|
|||
|
END (* for *);
|
|||
|
|
|||
|
SetPenColor(Black);
|
|||
|
DrawFrame; (*Draw a box around the plot for this array *)
|
|||
|
|
|||
|
Move(0.75,4.7);
|
|||
|
SetLabelOrigin(CenterRight);
|
|||
|
SetCharSize(Small);
|
|||
|
CASE IPlot OF (*Put the appropriate title on each plot*)
|
|||
|
UpLeft: DrawLabel("5 terms in series");
|
|||
|
|UpRight: DrawLabel("10 terms in series");
|
|||
|
|LowLeft:DrawLabel("20 terms in series");
|
|||
|
|LowRight:DrawLabel("100 terms in series");
|
|||
|
END (* case *);
|
|||
|
END (* for *);
|
|||
|
|
|||
|
(*Now that all four plots have been drawn, put a title and
|
|||
|
the formula in the middle area on the page *)
|
|||
|
SetPlotArea(0.0,100.0,0.0,100.0); (* Set to full screen *);
|
|||
|
SetScaledArea(0.0,100.0,0.0,100.0);
|
|||
|
SetScale(0.0,100.0,0.0,100.0);
|
|||
|
|
|||
|
Move(9.0,53.0);
|
|||
|
SetCharSize(Med);
|
|||
|
SetLabelOrigin(CenterRight);
|
|||
|
DrawLabel("FOURIER SERIES APPROXIMATION TO A SAWTOOTH WAVE");
|
|||
|
Move(17.0,47.0);
|
|||
|
SetCharSize(Small);
|
|||
|
DrawLabel("y = 2 {sin(x) - sin(2x)/2 + sin(3x)/3 - sin(4x)/4 + ... }");
|
|||
|
|
|||
|
CloseGraphics; (* Clean up and restore the system *)
|
|||
|
END Example.
|
|||
|
|
|||
|
|