💾 Archived View for spam.works › mirrors › textfiles › computers › auping.asc captured on 2023-12-28 at 17:13:07.
View Raw
More Information
⬅️ Previous capture (2023-06-14)
-=-=-=-=-=-=-
_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.