home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hacker Chronicles 2
/
HACKER2.BIN
/
140.DRAWGRAF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1988-06-28
|
32KB
|
888 lines
UNIT DrawGraf;
INTERFACE
USES
Graph,
{$IFDEF DOSCrt}
DOSCrt,
{$ELSE}
Crt,
{$ENDIF}
DOS,
Printer,
Extended_Reals,
MathLib0,
GraphText;
{----------------------------------------------------------------------------}
{--- Types of plots available for graphs ---}
{----------------------------------------------------------------------------}
CONST
Linear = 1;
Logarithmic = 2;
LogLin = 3;
LinLog = 4;
{----------------------------------------------------------------------------}
{--- Graphics mode variables for graphics system. ---}
{----------------------------------------------------------------------------}
VAR
GraphDriver : INTEGER;
GraphMode : INTEGER;
{----------------------------------------------------------------------------}
{--- DrawGraph graphs data to the screen. ---}
{----------------------------------------------------------------------------}
{--- ---}
{--- INPUT parameters are ---}
{--- x_ptr : pointer to the x-axis data values ---}
{--- y_ptr : pointer to the y-axis data values ---}
{--- NumPlotPoints : number of (x,y) points in arrays to plot ---}
{--- Plot : type of plot to be done (linear, logarithmic, etc.) ---}
{--- left_x : left edge of area of screen to display plot ---}
{--- top_y : top edge of area of screen to display plot ---}
{--- right_x : right edge of area of screen to display plot ---}
{--- bottom_y : bottom edge of boundary to display plot ---}
{--- horiz_units : x-axis label ---}
{--- vert_units : y-axis label ---}
{--- ---}
{--- OUTPUT parameters are ---}
{--- XDelay : distance of first x value from origin ---}
{--- YDelay : distance of first y value from origin ---}
{--- error : indicates success or failure of DrawGraph, using ---}
{--- error codes given below. ---}
{--- ---}
{----------------------------------------------------------------------------}
{--- VALID ERROR MESSAGES: ---}
{--- 0 : no error ---}
{--- 1 : zero or negative value on log scale ---}
{--- 2 : insufficient memory to create necessary data arrays ---}
{--- 3 : data out of range of graphing routine ---}
{----------------------------------------------------------------------------}
PROCEDURE DrawGraph ( VAR x_ptr {untyped parameter};
VAR y_ptr {untyped parameter};
NumPlotPoints : INTEGER;
Plot : BYTE;
left_x : INTEGER;
top_y : INTEGER;
right_x : INTEGER;
bottom_y : INTEGER;
VAR XDelay : REAL;
VAR YDelay : REAL;
horiz_units : string;
vert_units : string;
VAR error : BYTE
);
PROCEDURE Print_Screen;
(****************************************************************************)
IMPLEMENTATION
CONST
MaxPlotPoints = 4100;
TYPE
PlotXYArray = ARRAY [1..MaxPlotPoints] OF REAL;
PlotXYPtr = ^PlotXYArray;
CONST
MajorTic = 8;
MinorTic = 4;
MinIntervals = 2;
MaxIntervals = 10;
MaxDecades = 5;
char_size = 4;
Power : string [10]
= '1000000000';
LogTable : ARRAY [2..9] OF REAL
= (0.3010, { log 2 }
0.4771, { log 3 }
0.6021, { log 4 }
0.6990, { log 5 }
0.7782, { log 6 }
0.8451, { log 7 }
0.9031, { log 8 }
0.9542); { log 9 }
TYPE
SkipType = 1..5;
WrkString = string [20];
WorldType = RECORD
x_1 : REAL; { minimum value of x in window }
sx_1 : INTEGER; { screen coordinate for x_1 }
y_1 : REAL; { minimum value of y in window }
sy_1 : INTEGER; { screen coordinate for y_1 }
x_2 : REAL; { maximum value of x in window }
sx_2 : INTEGER; { screen coordinate for x_2 }
y_2 : REAL; { maximum value of y in window }
sy_2 : INTEGER; { screen coordinate for y_2 }
END; {RECORD}
VAR
XLinear : BOOLEAN; { is x axis linear? }
YLinear : BOOLEAN; { is y axis linear? }
i : INTEGER; { counter variable }
start : INTEGER; { first nonnegative point in array }
ScaleX : REAL; { scale x data to proper range }
ScaleY : REAL; { scale y data to proper range }
FactorX : INTEGER; { increment on linear x axis }
FactorY : INTEGER; { increment on linear y axis }
NumIntervalsX : BYTE; { num of x intervals to plot }
PosIntervalsX : BYTE; { num of positive x intervals }
NegIntervalsX : BYTE; { num of negative x intervals }
NumIntervalsY : BYTE; { num of y intervals to plot }
PosIntervalsY : BYTE; { num of positive y intervals }
NegIntervalsY : BYTE; { num of negative y intervals }
NumDecadesX : BYTE; { num of x decades to plot }
NumDecadesY : BYTE; { num of y decades to plot }
PlotX : INTEGER; { x coordinate to draw char at }
PlotY : INTEGER; { y coordinate to draw char at }
temp : REAL; { temp var for swapping coordinates }
ZeroX : INTEGER; { x coordinate of graph's origin }
ZeroY : INTEGER; { y coordinate of graph's origin }
SkipX : SkipType; { how many x tic marks to skip }
SkipY : SkipType; { how many y tic marks to skip }
world : Worldtype; { limits of values to be graphed }
{----------------------------------------------------------------------------}
{--- ---}
{--- Low level graphics routines for use in DrawGraph. ---}
{--- ---}
{----------------------------------------------------------------------------}
{----------------------------------------------------------------------------}
{- SetUpWorld matches a world coordinate system to a window on the screen -}
{----------------------------------------------------------------------------}
PROCEDURE SetUpWorld (x1, y1, x2, y2 : REAL;
sx1,sy1,sx2,sy2 : INTEGER);
BEGIN {SetUpWorld}
WITH world DO BEGIN
x_1:=x1; sx_1:=sx1;
y_1:=y1; sy_1:=sy1;
x_2:=x2; sx_2:=sx2;
y_2:=y2; sy_2:=sy2;
END; {WITH}
END; {SetUpWorld}
{----------------------------------------------------------------------------}
{- WhereX converts an independent world coordinate to a screen coordinate -}
{----------------------------------------------------------------------------}
FUNCTION WhereX (x:REAL) : INTEGER; { finds screen coordinate of x }
BEGIN {WhereX}
WITH world DO
WhereX:=sx_1+round(((x-x_1)/(x_2-x_1))*(sx_2-sx_1));
END; {WhereX}
{----------------------------------------------------------------------------}
{- WhereY converts a dependent world coordinate to a screen coordinate -}
{----------------------------------------------------------------------------}
FUNCTION WhereY (y:REAL) : INTEGER; { finds screen coordinate of y }
BEGIN {WhereY}
WITH world DO
WhereY:=sy_1+round(((y-y_1)/(y_2-y_1))*(sy_2-sy_1));
END; {WhereY}
{----------------------------------------------------------------------------}
{- DrawLine draws a line from world coordinates (x1,y1) to (x2,y2). -}
{----------------------------------------------------------------------------}
PROCEDURE DrawLine (x1, y1, x2, y2 : REAL);
VAR
sx1 : INTEGER; { x1 in screen coordinates }
sx2 : INTEGER; { x2 in screen coordinates }
sy1 : INTEGER; { y1 in screen coordinates }
sy2 : INTEGER; { y2 in screen coordinates }
BEGIN {DrawLine}
sx1:=WhereX (x1);
sy1:=WhereY (y1);
sx2:=WhereX (x2);
sy2:=WhereY (y2);
Line (sx1,sy1,sx2,sy2);
END; {DrawLine}
{----------------------------------------------------------------------------}
{- Drop searches data for the first nonnegative data point on both the x- -}
{- and y-axes. If either axis is logarithmic, then that nonnegative data -}
{- point becomes the first point to be graphed. -}
{----------------------------------------------------------------------------}
PROCEDURE Drop ( x : PlotXYPtr;
y : PlotXYPtr;
Plot : BYTE;
VAR start : INTEGER);
VAR
i : INTEGER; { number of nonpositive x elements }
j : INTEGER; { number of nonpositive y elements }
BEGIN {Drop}
start:=1;
i:=1;
j:=1;
IF NOT XLinear THEN
WHILE x^[i] <= 0 DO inc(i,1);
IF NOT YLinear THEN
WHILE y^[j] <= 0 DO inc(j,1);
CASE Plot of
1: start:=1;
2: IF i >= j
THEN start:=i
ELSE start:=j;
3: start:=i;
4: start:=j;
END; {CASE}
END; {Drop}
{----------------------------------------------------------------------------}
{- MinMaxLin finds the minimum and maximum values on a single axis of the -}
{- input data to be displayed on a linear graph. -}
{----------------------------------------------------------------------------}
PROCEDURE MinMaxLin ( VAR min : REAL;
VAR max : REAL;
VAR Scale : REAL;
VAR Factor : INTEGER;
VAR NumIntervals : BYTE;
VAR PosIntervals : BYTE;
VAR NegIntervals : BYTE;
VAR Error : BYTE
);
CONST
MaxPower = 21;
StepSize : array [1..9] of INTEGER
= (1,2,5,10,20,50,100,200,500);
VAR
OKAY : BOOLEAN; { Done with loop yet? }
i : INTEGER; { Counter variable }
delta : REAL; { Max - min }
MinFudge : BOOLEAN; { Fudge factor for min computations }
MaxFudge : BOOLEAN; { Fudge factor for max computations }
BEGIN {MinMaxLin}
delta:=abs(max-min);
i:=MaxPower+3;
REPEAT
dec (i,3);
IF i < -MaxPower THEN BEGIN
Error:=3;
Exit;
END; {IF}
Scale:=exp10(i);
UNTIL ((5 <= (delta/Scale)) AND ((delta/Scale) < 5000));
MinFudge:=false;
MaxFudge:=false;
IF (abs(min/Scale) > MaxInt) THEN BEGIN
min:=min/1000;
MinFudge:=true;
END; {IF}
IF (abs(max/Scale) > MaxInt) THEN BEGIN
max:=max/1000;
MaxFudge:=true;
END; {IF}
IF min < 0
THEN min:=pred(trunc(min/Scale))
ELSE min:= trunc(min/Scale);
IF max < 0
THEN max:= trunc(max/Scale)
ELSE max:=succ(trunc(max/Scale));
IF max < 0
THEN max:=0
ELSE IF min > 0
THEN min:=0;
IF MinFudge THEN min:=min*1000;
IF MaxFudge THEN max:=max*1000;
i:=1;
NumIntervals:=10;
OKAY:=false;
REPEAT
Factor:=StepSize[i];
IF ((NumIntervals*Factor) >= (max-min))
THEN OKAY:=true
ELSE i:=succ(i);
UNTIL (OKAY OR (i = 10));
min:=min*Scale;
max:=max*Scale;
IF (min >= 0)
THEN BEGIN
PosIntervals:=NumIntervals;
NegIntervals:=0;
min:=0;
max:=NumIntervals*Factor*Scale;
END {THEN}
ELSE IF (max <= 0)
THEN BEGIN
PosIntervals:=0;
NegIntervals:=NumIntervals;
min:=-NumIntervals*Factor*Scale;
max:=0;
END {ELSE IF}
ELSE {min < 0 < max}
BEGIN
PosIntervals:=trunc(max/(max-min)*NumIntervals+1);
NegIntervals:=trunc(min/(min-max)*NumIntervals+1);
NumIntervals:=PosIntervals+NegIntervals;
min:=-NegIntervals*Factor*Scale;
max:= PosIntervals*Factor*Scale;
END; {ELSE}
END; {MinMaxLin}
{----------------------------------------------------------------------------}
{- MinMaxLog finds the minimum and maximum values on a single axis of the -}
{- input data to be displayed on a logarithmic graph. -}
{----------------------------------------------------------------------------}
PROCEDURE MinMaxLog ( VAR min : REAL;
VAR max : REAL;
VAR Scale : REAL;
VAR NumDecades : BYTE
);
BEGIN {MinMaxLog}
IF min > 0 THEN IF min < 1
THEN min:=exp10(pred(trunc(log(min))))
ELSE min:=exp10 (trunc(log(min)));
IF max > 0 THEN IF max < 1
THEN max:=exp10 (trunc(log(max)))
ELSE max:=exp10(succ(trunc(log(max))));
IF (min = 0) THEN min:=max*exp10(-MaxDecades);
NumDecades:=round(log(max)-log(min));
IF NumDecades > MaxDecades THEN BEGIN
min:=exp10(round(log(max)-MaxDecades));
NumDecades:=MaxDecades;
END; {IF}
Scale:=min;
END; {MinMaxLog}
{----------------------------------------------------------------------------}
{- Skip determines the number of tic marks to skip labelling on a linear -}
{- axis; e.g. if SkipNum = 4, then every fourth tic mark is labelled. -}
{----------------------------------------------------------------------------}
PROCEDURE Skip ( d : INTEGER;
s : INTEGER;
i : INTEGER;
VAR SkipNum : SkipType
);
BEGIN {Skip}
IF ((d<=s/5) AND (i>=4))
THEN SkipNum:=5
ELSE IF ((d<=s/4) AND (i>=6))
THEN SkipNum:=4
ELSE IF ((d<=s/3) AND (i>=8))
THEN SkipNum:=3
ELSE IF ((d<=s/2) AND (i>=10))
THEN SkipNum:=2
ELSE SkipNum:=1;
END; {Skip}
{----------------------------------------------------------------------------}
{- LinearAxis draws a linear axis -}
{----------------------------------------------------------------------------}
PROCEDURE LinearAxis ( axis : char;
min : REAL;
max : REAL;
Scale : REAL;
Factor : INTEGER;
NumIntervals : BYTE;
PosIntervals : BYTE;
NegIntervals : BYTE;
units : string
);
VAR
i : INTEGER;
j : INTEGER;
Plot1 : INTEGER;
Plot2 : INTEGER;
OutScale : INTEGER;
OutX : INTEGER;
OutY : INTEGER;
OutFactor : WrkString;
XAXIS : BOOLEAN;
z1 : INTEGER;
z2 : INTEGER;
z3 : INTEGER;
z4 : INTEGER;
for_limit : INTEGER;
OK_to_Draw : BOOLEAN;
outstr : string [20];
BEGIN {LinearAxis}
XAXIS:=(UpCase(axis) = 'I');
WITH world DO IF XAXIS
THEN BEGIN
z1:=sx_1; z2:=sx_2; z3:=sy_1; z4:=sy_2;
END
ELSE BEGIN
z1:=sy_1; z2:=sy_2; z3:=sx_1; z4:=sx_2;
END;
IF XAXIS
THEN BEGIN
Plot1:=WhereX (0);
Line (Plot1,z3,Plot1,z4);
Line (z1,z3,z2,z3);
Line (z1,z4,z2,z4);
PlotX:=Plot1;
PlotY:=z3+char_height;
ZeroX:=Plot1;
END
ELSE BEGIN
Plot1:=WhereY (0);
Line (z3,Plot1,z4,Plot1);
Line (z3,z1,z3,z2);
Line (z4,z1,z4,z2);
PlotX:=z3-4*char_width;
PlotY:=Plot1-(char_height div 2);
ZeroY:=Plot1;
END;
OutTextXY (PlotX,PlotY,'0');
FOR j:=1 TO 2 DO BEGIN
for_limit:=PosIntervals+(j-1)*(NegIntervals-PosIntervals);
FOR i:=1 TO for_limit DO BEGIN
Plot2:=Plot1+(3-2*j)*round(i*(z2-z1)/NumIntervals);
Str ((3-2*j)*i*Factor,OutFactor);
IF XAXIS
THEN BEGIN
Line (Plot2,z3,Plot2,z3-MajorTic);
Line (Plot2,z4,Plot2,z4+MajorTic);
PlotX:=Plot2-(Length(OutFactor) div 2)*char_width;
PlotY:=z3+char_height;
OK_to_Draw:=(i mod SkipX = 0);
END {THEN}
ELSE BEGIN
Line (z3,Plot2,z3+MajorTic,Plot2);
Line (z4,Plot2,z4-MajorTic,Plot2);
PlotX:=z3-(3+j)*char_width;
PlotY:=Plot2-(char_height div 2);
OK_to_Draw:=(i mod SkipY = 0);
END;
IF OK_to_Draw THEN OutTextXY (PlotX,PlotY,OutFactor);
END; {FOR i}
END; {FOR j}
IF XAXIS
THEN BEGIN
OutX:=((z1+z2) div 2)-4*char_width;
OutY:=z3+3*char_height;
END {THEN}
ELSE BEGIN
OutX:=z3-(10+MaxDecades)*char_width;
OutY:=(z1+z2-char_height) div 2;
END; {ELSE}
OutScale:=round(log(Scale));
Str (OutScale,OutFactor);
PlotX:=OutX;
PlotY:=OutY;
IF OutFactor <> '0' THEN BEGIN
outstr:='(x10 )';
OutTextXY (PlotX,PlotY,outstr);
PlotX:=OutX;
PlotY:=OutY-(char_height div 2);
outstr:=' '+OutFactor;
OutTextXY (PlotX,PlotY,outstr);
IF XAXIS
THEN BEGIN
PlotX:=OutX+12*char_width;
PlotY:=OutY;
END {THEN}
ELSE BEGIN
PlotX:=OutX;
PlotY:=OutY+2*char_height;
END; {ELSE}
END; {THEN}
OutTextXY (PlotX,PlotY,units);
END; {LinearAxis}
{----------------------------------------------------------------------------}
{- LogAxis draws a logarithmic axis -}
{----------------------------------------------------------------------------}
PROCEDURE LogAxis ( axis : char;
min : REAL;
max : REAL;
Scale : REAL;
NumDecades : BYTE;
units : string
);
VAR
i : INTEGER;
j : INTEGER;
k : INTEGER;
Plot1 : INTEGER;
Plot2 : INTEGER;
NewPlot : INTEGER;
OutX : INTEGER;
OutY : INTEGER;
OutScale : INTEGER;
OutFactor : Wrkstring;
outstr : WrkString;
z1 : INTEGER;
z2 : INTEGER;
z3 : INTEGER;
z4 : INTEGER;
XAXIS : BOOLEAN;
BEGIN {LogAxis}
XAXIS:=(UpCase(axis) = 'I');
WITH world DO IF XAXIS
THEN BEGIN
z1:=sx_1; z2:=sx_2; z3:=sy_1; z4:=sy_2;
END
ELSE BEGIN
z1:=sy_1; z2:=sy_2; z3:=sx_1; z4:=sx_2;
END;
IF XAXIS
THEN BEGIN
Line (z1,z3,z2,z3);
Line (z1,z4,z2,z4);
END
ELSE BEGIN
Line (z3,z1,z3,z2);
Line (z4,z1,z4,z2);
END;
Plot1:=z1;
FOR i:=1 TO NumDecades+1 DO BEGIN
NewPlot:=round(z1+i*(z2-z1)/NumDecades);
FOR k:=1 TO i DO OutFactor[k]:=power[k];
OutFactor[0]:=char(i);
IF XAXIS
THEN BEGIN
Line (Plot1,z3,Plot1,z3-MajorTic);
Line (Plot1,z4,Plot1,z4+MajorTic);
PlotX:=Plot1-(i*char_width) div 2;
PlotY:=z3+char_height;
END
ELSE BEGIN
Line (z3,Plot1,z3+MajorTic,Plot1);
Line (z4,Plot1,z4-MajorTic,Plot1);
PlotX:=z3-(MaxDecades+1)*char_width;
PlotY:=Plot1;
END;
OutTextXY (PlotX,PlotY,OutFactor);
IF i <= NumDecades THEN FOR j:=2 TO 9 DO BEGIN
Plot2:=round(Plot1+(NewPlot-Plot1)*LogTable[j]);
IF XAXIS
THEN BEGIN
Line (Plot2,z3,Plot2,z3-MinorTic);
Line (Plot2,z4,Plot2,z4+MinorTic);
END
ELSE BEGIN
Line (z3,Plot2,z3+MinorTic,Plot2);
Line (z4,Plot2,z4-MinorTic,Plot2);
END;
END; {FOR j}
Plot1:=NewPlot;
END; {FOR i}
IF XAXIS
THEN BEGIN
OutX:=(z1+z2) div 2 - 4*char_width;
OutY:=z3+3*char_height;
END
ELSE BEGIN
OutX:=z3-(10+MaxDecades)*char_width;
OutY:=(z1+z2+char_height) div 2;
END;
OutScale:=round(log(Scale));
Str (OutScale,OutFactor);
PlotX:=OutX;
PlotY:=OutY;
IF OutFactor <> '0' THEN BEGIN
outstr:='(x10 )';
OutTextXY (PlotX,PlotY,outstr);
PlotX:=OutX;
PlotY:=OutY-(char_height div 2);
outstr:=' '+OutFactor;
OutTextXY (PlotX,PlotY,outstr);
IF XAXIS
THEN BEGIN
PlotX:=OutX+12*char_width;
PlotY:=OutY;
END {THEN}
ELSE BEGIN
PlotX:=OutX;
PlotY:=OutY+2*char_height;
END; {ELSE}
END; {THEN}
OutTextXY (PlotX,PlotY,units);
END; {LogAxis}
{----------------------------------------------------------------------------}
{- LinearScale scales the linear axis data to the world coordinate system -}
{----------------------------------------------------------------------------}
PROCEDURE LinearScale ( VAR z : PlotXYPtr;
VAR min : REAL;
VAR max : REAL;
Scale : REAL;
N : INTEGER
);
VAR i : INTEGER;
BEGIN {LinearScale}
FOR i:=1 TO N DO
z^[i]:=z^[i]/Scale;
min:=min/Scale;
max:=max/Scale;
END; {LinearScale}
{----------------------------------------------------------------------------}
{- LogScale scales the logarithmic data to the world coordinate system -}
{----------------------------------------------------------------------------}
PROCEDURE LogScale ( VAR z : PlotXYPtr;
VAR min : REAL;
VAR max : REAL;
Scale : REAL;
N : INTEGER
);
VAR i : INTEGER;
BEGIN {LogScale}
FOR i:=1 TO N DO BEGIN
IF (z^[i] < min) THEN z^[i]:=min;
z^[i]:=log(z^[i]/Scale);
END; {FOR}
min:=log(min/Scale);
max:=log(max/Scale);
END; {LogScale}
{----------------------------------------------------------------------------}
{- GraphArray actually plots the data on the screen -}
{----------------------------------------------------------------------------}
PROCEDURE GraphArray (x : PlotXYPtr;
y : PlotXYPtr;
N : INTEGER);
VAR
new_x : INTEGER;
new_y : INTEGER;
old_x : INTEGER;
old_y : INTEGER;
i : INTEGER;
BEGIN {GraphArray}
new_x:=WhereX (x^[1]);
new_y:=WhereY (y^[1]);
FOR i:=2 TO N DO BEGIN
old_x:=new_x;
old_y:=new_y;
new_x:=WhereX (x^[i]);
new_y:=WhereY (y^[i]);
Line (old_x,old_y,new_x,new_y);
END; {FOR}
END; {GraphArray}
{----------------------------------------------------------------------------}
PROCEDURE DrawGraph ( VAR x_ptr {untyped parameter};
VAR y_ptr {untyped parameter};
NumPlotPoints : INTEGER;
Plot : BYTE;
left_x : INTEGER;
top_y : INTEGER;
right_x : INTEGER;
bottom_y : INTEGER;
VAR XDelay : REAL;
VAR YDelay : REAL;
horiz_units : string;
vert_units : string;
VAR error : BYTE
);
VAR
x : PlotXYPtr;
y : PlotXYPtr;
minx : REAL;
maxx : REAL;
miny : REAL;
maxy : REAL;
BEGIN {DrawGraph}
x:=PlotXYPtr (x_ptr);
y:=PlotXYPtr (y_ptr);
error:=0;
SetTextStyle (SmallFont,HorizDir,char_size);
left_x:=left_x+(11+MaxDecades)*char_width;
bottom_y:=bottom_y-3*char_height;
XLinear:=((Plot = Linear) OR (Plot = LinLog));
YLinear:=((Plot = Linear) OR (Plot = LogLin));
XDelay:=x^[1];
YDelay:=0;
FOR i:=1 TO NumPlotPoints DO BEGIN
x^[i]:=x^[i]-XDelay;
y^[i]:=y^[i]-YDelay;
END; {FOR}
Drop (x,y,Plot,start);
FOR i:=start TO NumPlotPoints DO BEGIN
x^[i-start+1]:=x^[i];
y^[i-start+1]:=y^[i];
END; {FOR}
NumPlotPoints:=NumPlotPoints-start+1;
minx:=x^[1];
maxx:=x^[1];
miny:=y^[1];
maxy:=y^[1];
FOR i:=2 TO NumPlotPoints DO BEGIN
IF minx > x^[i]
THEN minx:=x^[i]
ELSE IF maxx < x^[i]
THEN maxx:=x^[i];
IF miny > y^[i]
THEN miny:=y^[i]
ELSE IF maxy < y^[i]
THEN maxy:=y^[i];
END; {FOR}
{--- If error in logarithmic data then exit procedure ---}
IF (NOT XLinear) AND (minx <= 0) THEN error:=1;
IF (NOT YLinear) AND (miny <= 0) THEN error:=1;
IF (error <> 0) THEN EXIT;
IF XLinear
THEN MinMaxLin (minx,maxx,ScaleX,FactorX,NumIntervalsX,
PosIntervalsX,NegIntervalsX,Error)
ELSE MinMaxLog (minx,maxx,ScaleX,NumDecadesX);
IF YLinear
THEN MinMaxLin (miny,maxy,ScaleY,FactorY,NumIntervalsY,
PosIntervalsY,NegIntervalsY,Error)
ELSE MinMaxLog (miny,maxy,ScaleY,NumDecadesY);
{--- If data is out of range then exit procedure ---}
IF (error <> 0) THEN EXIT;
SetUpWorld (minx,miny,maxx,maxy,left_x,bottom_y,right_x,top_y);
IF XLinear
THEN BEGIN
Skip ((right_x-left_x),GetMaxX,NumIntervalsX,SkipX);
LinearAxis ('i',minx,maxx,ScaleX,FactorX,NumIntervalsX,
PosIntervalsX,NegIntervalsX,horiz_units);
LinearScale (x,minx,maxx,ScaleX,NumPlotPoints);
END {THEN}
ELSE BEGIN
LogAxis ('i',minx,maxx,ScaleX,NumDecadesX,horiz_units);
LogScale (x,minx,maxx,ScaleX,NumPlotPoints);
END; {THEN}
IF YLinear
THEN BEGIN
Skip ((bottom_y-top_y),GetMaxY,NumIntervalsY,SkipY);
LinearAxis ('d',miny,maxy,ScaleY,FactorY,NumIntervalsY,
PosIntervalsY,NegIntervalsY,vert_units);
LinearScale (y,miny,maxy,ScaleY,NumPlotPoints);
END {THEN}
ELSE BEGIN
LogAxis ('d',miny,maxy,ScaleY,NumDecadesY,vert_units);
LogScale (y,miny,maxy,ScaleY,NumPlotPoints);
END; {ELSE}
WITH world DO
SetUpWorld (minx,miny,maxx,maxy,sx_1,sy_1,sx_2,sy_2);
GraphArray (x,y,NumPlotPoints);
END; {DrawGraph}
{----------------------------------------------------------------------------}
PROCEDURE Print_Screen;
CONST
FormFeed = #12; { formfeed for an Epson-compatible printer }
VAR
Reg : Registers; { variable to read/write to the 8088 registers }
BEGIN {Print_Screen}
Intr ($5,Reg);
WriteLn (lst,FormFeed);
END; {Print_Screen}
(****************************************************************************)
VAR
Error : INTEGER;
PROCEDURE CgaDriverProc; external;
{$L \pascal4\graphix\CGA.OBJ }
PROCEDURE EgaVgaDriverProc; external;
{$L \pascal4\graphix\EGAVGA.OBJ }
PROCEDURE HercDriverProc; external;
{$L \pascal4\graphix\HERC.OBJ }
PROCEDURE SmallFontProc; external;
{$L c:\pascal4\graphix\LITT.OBJ }
PROCEDURE Abort(Msg : string);
BEGIN {Abort}
Writeln(Msg, ': ', GraphErrorMsg(GraphResult));
Halt(1);
END; {Abort}
BEGIN {Initialization section}
{ Register all the drivers }
IF RegisterBGIdriver (@CGADriverProc) < 0 THEN Abort('CGA');
IF RegisterBGIdriver (@EGAVGADriverProc) < 0 THEN Abort('EGA/VGA');
IF RegisterBGIdriver (@HercDriverProc) < 0 THEN Abort('Herc');
{ Register all the fonts }
IF RegisterBGIfont (@SmallFontProc) < 0 THEN Abort('Small');
GraphDriver := Detect; { autodetect the hardware }
DetectGraph (GraphDriver, GraphMode); { activate graphics }
IF GraphDriver = grNotDetected THEN BEGIN { any errors? }
GraphDriver:=CGA;
GraphMode :=CGAHi;
END; {IF}
InitGraph (GraphDriver,GraphMode,'');
IF GraphResult <> grOk THEN BEGIN { any errors? }
WriteLn ('Graphics initialization error: ', GraphErrorMsg(GraphDriver));
Halt(1);
END;
RestoreCrtMode;
Exec ('\command.com,','/c graphics');
END. {UNIT DrawGraf}