home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / LANGUAGS / PASCAL / XYPLOT.PAS < prev   
Pascal/Delphi Source File  |  2000-06-30  |  5KB  |  210 lines

  1. module xyplot;
  2.  
  3. {
  4.  
  5. XYPLOT - Generate 2-D Plots of X,Y Data Pairs
  6.     Derived from the FORTRAN IV Subroutine XYPLT in the Book
  7.     "Digital Computations in Basic Circuit Theory" by L.P. Huelsman
  8.     PASCAL/MT+ Coding and Algorithm Enhancements by Richard Conn
  9.  
  10. Calling Form --
  11.     rcode = xyplot (device, ndata, nsx, nsy, nnp, x, y);
  12.  
  13. Passed Parameters --
  14.     device    A String (STR) Specifying the Output Device/File; One of:
  15.             CON:    = Console
  16.             LST:    = Printer
  17.             <File>    = Disk File, Like PLOT1.TXT or A:Plot
  18.     ndata    Number of valid data points in the x,y rarrays
  19.     nsx    Maximum Value of X Points
  20.     nsy    Maximum Value of Y Points (Minimum Value = NSY - 100)
  21.     nnp    Range of X Points (NSX - Minimum Value of X Points)
  22.     x, y    rarrays of the X,Y input Point values
  23.  
  24. Result Codes (Type Integer) Returned --
  25.     0    No Error
  26.     1    Error in Opening Output File
  27.     2    Error in Closing Output File
  28.  
  29. Special Types --
  30.     See the following TYPE Definition for the types STR for the
  31.     device name and RARRAY for the passed data.
  32.  
  33. }
  34.  
  35. const
  36.     max_elt = 200; { Maximum Number of Array Elements Permitted }
  37.     strl = 20; { Maximum Number of Characters in a String Vector STR }
  38. type
  39.     rarray = array [1..max_elt] of real;
  40.     str = string[strl];
  41.  
  42. function xyplot (device : str; ndata, nsx, nsy, nnp : integer; x, y : rarray) :
  43.     integer;
  44.  
  45. const
  46.     jn = '-';
  47.     jp = '+';
  48.     ji = 'I';
  49.     jb = ' ';
  50.     jz = '$';
  51.     jx = 'X';
  52. var
  53.     ofile : text;
  54.     line : array [1..101] of char;
  55.     i, j, l, np, dash, index : integer;
  56.     nx, nx_next : integer;
  57.     xns, yns, xnp : real;
  58.     rcode : integer;
  59.  
  60. procedure clear (jint, jopen : char);
  61. var
  62.     i, j, idx : integer;
  63. begin
  64.     { Initialize Line Image to Dashes }
  65.     idx := 0;
  66.     for i:=1 to 10 do begin
  67.         idx := idx + 1;
  68.         line[idx] := jint;  { Intersect Char }
  69.         for j:=1 to 9 do begin
  70.             idx := idx + 1;
  71.             line[idx] := jopen;  { Level Char }
  72.         end;
  73.     end;
  74.     line[101] := jint;  { Last Intersect Char }
  75. end;
  76.  
  77. procedure capitalize (var s : str);
  78. var    i : integer;
  79. begin
  80.     for i:=1 to strl do
  81.         if (s[i] > 'a') and (s[i] <= 'z') then
  82.             s[i] := chr(ord(s[i]) - ord('a') + ord('A'));
  83. end;
  84.  
  85. procedure clrblank;
  86. begin
  87.     { Initialize Line Image to Blanks }
  88.     clear (ji, jb);
  89. end;
  90.  
  91. procedure clrdash;
  92. begin
  93.     { Initialize Line Image to Dashes }
  94.     clear (jp, jn);
  95. end;
  96.  
  97. procedure xchg (var a,b : real);
  98. var
  99.     temp : real;
  100. begin
  101.     { Exchange real numbers A and B }
  102.     temp := a;
  103.     a := b;
  104.     b := temp;
  105. end;
  106.  
  107. procedure sety (idx : integer);
  108. var
  109.     ny : integer;
  110. begin
  111.     ny := trunc (y[idx] + 101.49999 - yns);
  112.     if ny < 1 then line[1] := jz { Off Scale }
  113.               else if ny > 101 then line[101] := jz
  114.                                else line[ny] := jx;
  115. end;
  116.  
  117. procedure setx (idx : integer);
  118. begin
  119.     { Scaled Value of Next X Element }
  120.     nx_next := trunc (x[idx] * 0.6 - xns + xnp + 0.49999);
  121.     if nx_next > np then nx_next := np; { Out of Range }
  122.     if nx_next < 0 then nx_next := 0;   { Out of Range }
  123. end;
  124.  
  125. procedure printline;
  126. var
  127.     i, nprint : integer;
  128. begin
  129.     if (dash mod 6) = 0 then begin
  130.         nprint := ((dash * 10) div 6) + nsx - nnp;
  131.         write(ofile, nprint:4); end
  132.     else write(ofile, '    ');
  133.     for i:=1 to 101 do write(ofile, line[i]); writeln(ofile);
  134.     dash := dash + 1; { Increment Line Counter }
  135. end;
  136.  
  137. begin { XYPLOT }
  138.  
  139.     { Set Result Code to OK }
  140.     rcode := 0;  { No Error }
  141.  
  142.     { Assign Output Device }
  143.     capitalize (device);  { Capitalize Output Device Name }
  144.     assign (ofile, device);  { Assign Device to File Spec }
  145.     rewrite (ofile);  { Rewind Device if Disk File }
  146.  
  147.     { Check for Successful Open of Output File and Perform XYPLOT if so }
  148.     if ioresult = 255 then rcode := 1  { Error in Opening File }
  149.     else begin { XYPLOT Function }
  150.  
  151.     { Arrange data in ascending order of X }
  152.     for i:=1 to ndata-1 do
  153.         for j:=i+1 to ndata do
  154.             if x[i] > x[j] then begin { Exchange }
  155.                 xchg (x[i], x[j]);
  156.                 xchg (y[i], y[j]);
  157.             end;
  158.  
  159.     { Print Ordinate Scale Figures }
  160.     write(ofile, ' ');  { Leading Space }
  161.     for i:=1 to 11 do begin
  162.         l := 10 * i - 110 + nsy;  { Compute Values }
  163.         write(ofile, l:4, '      ');  { Write Values }
  164.     end;
  165.     writeln(ofile);  { New Line after Ordinate Scale Values }
  166.  
  167.     { Initialize Key Values }
  168.     dash := 0; { Initialize dash line indicator }
  169.     np := (nnp div 10) * 6; xnp := np;
  170.     xns := (nsx div 10) * 6; yns := nsy;
  171.     index := 1;
  172.     setx(index);  { Scaled Value of nx_next }
  173.  
  174.     repeat { Main Loop }
  175.         { Set up current line }
  176.         if (dash mod 6) = 0 then clrdash else clrblank;
  177.  
  178.         { Load Values into current line if X Coordinates Match }
  179.         if dash >= nx_next then
  180.            repeat { Plot all Y Values which belong to current X }
  181.             nx := nx_next;  { Scaled Value of Current X }
  182.  
  183.             { Scaled Value of Current Y }
  184.             sety(index);
  185.  
  186.             index := index + 1;  { Advance to next data elt }
  187.             setx(index); { Compute Next X }
  188.            until (nx_next <> nx) or (index = ndata);
  189.  
  190.         if (index = ndata) and (nx_next = nx) then sety(index);
  191.  
  192.         printline;  { Print Graph }
  193.     until index = ndata;
  194.  
  195.     if nx_next <> nx then begin
  196.         sety(index);
  197.         printline;
  198.     end;
  199.  
  200.     { Close Output File }
  201.     close(ofile,i);
  202.     if i=255 then rcode := 2;  { Error in Closing File }
  203.  
  204.     end; { XYPLOT Function }
  205.  
  206.     xyplot := rcode;  { Setup Return Code }
  207.  
  208. end; { XYPLOT }
  209. modend.
  210.