💾 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.