home *** CD-ROM | disk | FTP | other *** search
- UNIT PGRAPH;
- INTERFACE
- USES Crt,Graph;
- CONST
- {$IFDEF CPU87} MaxInt=2147483647; {$ENDIF}
- nmax=200;
- CONST
- Black:BYTE=0; Blue:BYTE=1; Green:BYTE=2; Cyan:BYTE=3;
- Red:BYTE=4; Magenta:BYTE=5; Brown:BYTE=6; LightGray:BYTE=7;
- DarkGray:BYTE=8; LightBlue:BYTE=9; LightGreen:BYTE=10; LightCyan:BYTE=11;
- LightRed:BYTE=12; LightMagenta:BYTE=13; Yellow:BYTE=14; White:BYTE=15;
- TYPE
- {$IFDEF CPU87} REAL=EXTENDED; {$ELSE}
- DOUBLE=REAL; SINGLE=REAL; EXTENDED=REAL; COMP=REAL; {$ENDIF}
- GeraetTyp = (Bildschirm,Drucker,Plotter);
- Vektor = ARRAY[1..nmax] OF REAL;
- strg80 = STRING[80];
- VAR
- Geraet:GeraetTyp; { fuer AngleTrueScale }
- GraphDriver,GraphMode,ErrorCode:INTEGER;
- OldExitProc:Pointer;
- Xaxmin,Xaxmax,Yaxmin,Yaxmax:REAL; { fuer USCALE }
- Uaxmin,Uaxmax,Vaxmin,Vaxmax:INTEGER; { fuer Graphikwindow }
-
- PROCEDURE AngleTrueScale(VAR x1,x2,y1,y2:REAL);
- PROCEDURE CloseGraphik;
- PROCEDURE Curve(VAR x,y:Vektor; n,Lintyp,Thickness,Color:WORD);
- PROCEDURE Curvex(VAR x,y:Vektor; n:WORD; Color:BYTE);
- FUNCTION EXP10(x:REAL):REAL;
- FUNCTION Exponent(x:REAL):INTEGER;
- PROCEDURE Extrema(z:Vektor; n:WORD; VAR zmin,zmax:REAL);
- PROCEDURE GraphikText(Text:strg80; Font, Size, TxtCol, Line:BYTE);
- PROCEDURE GraphikWindow(x1,x2,y1,y2:INTEGER);
- PROCEDURE LinaxScale(VAR a,b,dx,Ex:REAL; Density:BYTE; VAR ExpStrg:strg80);
- FUNCTION LOG10(x:REAL):REAL;
- PROCEDURE LogXAxis(LogX1,LogX2:REAL; XText:strg80; Font,Size:WORD);
- PROCEDURE LogYAxis(LogY1,LogY2:REAL; YText:strg80; Font,Size:WORD);
- PROCEDURE OpenGraphik;
- FUNCTION RealToString(x:REAL):strg80;
- PROCEDURE Scale(x,y:REAL; VAR u,v:INTEGER);
- PROCEDURE Uscale(VAR x1,x2,y1,y2:REAL; Origin,AngleTrue:BOOLEAN; Expans:REAL);
- PROCEDURE XAxis(x1,x2:REAL; XText:strg80; Font,Size:WORD);
- PROCEDURE Xgrid(x:REAL);
- PROCEDURE Xmark(x:REAL; VAR u:INTEGER; Len:BYTE);
- PROCEDURE YAxis(y1,y2:REAL; YText:strg80; Font,Size:WORD);
- PROCEDURE Ymark(y:REAL; VAR v:INTEGER; Len:BYTE);
- PROCEDURE Ygrid(y:REAL);
-
- IMPLEMENTATION
-
- PROCEDURE AngleTrueScale; { Winkeltreue Skalierung }
- VAR C,dx,dy,xx,yy,xm,ym,F:REAL; Xasp,Yasp:WORD;
- BEGIN
- IF Geraet=Bildschirm THEN BEGIN { Laenge/Breite-Faktor }
- GetAspectRatio(Xasp,Yasp);
- F:=(Xasp/Yasp)*(Abs(Uaxmin-Uaxmax)/Abs(Vaxmin-Vaxmax)); END
- ELSE BEGIN
- F:=(2/3)*(Abs(Uaxmin-Uaxmax)/Abs(Vaxmin-Vaxmax))
- END;
- dx:=Abs(x2-x1);
- dy:=Abs(y2-y1);
- IF dx>=dy THEN BEGIN
- yy:=0.5*dx/F; IF y1>y2 THEN yy:=-yy; { y-Achse strecken }
- ym:=0.5*(y1+y2); y1:=ym-yy; y2:=ym+yy; END
- ELSE BEGIN
- xx:=0.5*dy*F; IF x1>x2 THEN xx:=-xx; { x-Achse strecken }
- xm:=0.5*(x1+x2); x1:=xm-xx; x2:=xm+xx;
- END;
- END;
-
- {$F+} PROCEDURE CloseGraphik; { Graphik beenden }
- BEGIN
- ExitProc:=OldExitProc;
- SetBkColor(Black);
- CloseGraph;
- DirectVideo:=TRUE;
- Window(1,1,80,25);
- END; {$F-}
-
- PROCEDURE Curve; { Polygonzug }
- VAR i,u1,v1,u2,v2:INTEGER;
- BEGIN
- SetLineStyle(Lintyp,0,Thickness); SetColor(Color);
- Scale(x[1],y[1],u1,v1);
- FOR i:=2 TO n DO BEGIN
- Scale(x[i],y[i],u2,v2); Line(u1,v1,u2,v2);
- u1:=u2; v1:=v2;
- END;
- END;
-
- PROCEDURE Curvex; { Punkte auftragen }
- VAR i,u,v:INTEGER;
- BEGIN
- FOR i:=1 TO n DO BEGIN
- Scale(x[i],y[i],u,v); PutPixel(u,v,Color);
- END;
- END;
-
- FUNCTION EXP10;
- VAR S:STRING[80]; E:REAL; Code:WORD;
- BEGIN
- IF x=Int(x) THEN BEGIN { 10 hoch Integer }
- Str(Trunc(x),S);
- Val(('1.0E'+S),E,Code); EXP10:=E; Exit;
- END;
- EXP10:=Exp(x*Ln(10)); { 10 hoch Real }
- END;
-
- FUNCTION Exponent; { Groessenordnung }
- VAR Ex,S:STRING[80]; n,Code:INTEGER; { einer Zahl }
- BEGIN
- Str(x,S); Ex:=Copy(S,Pos('E',S)+1,Length(S));
- Val(Ex,n,Code); Exponent:=n;
- END;
-
- PROCEDURE Extrema; { Maximum und Minimum }
- VAR i:WORD; { des Vektors z[1..n] }
- BEGIN
- zmin:=z[1]; zmax:=z[1];
- FOR i:=2 TO n DO BEGIN
- IF z[i]<zmin THEN zmin:=z[i];
- IF z[i]>zmax THEN zmax:=z[i];
- END;
- END;
-
- PROCEDURE GraphikText; { Textausgabe ins }
- VAR Xpos,Ypos:INTEGER; { Graphikfenster }
- BEGIN
- IF (Font>4) OR (Font<0) THEN Font:=1;
- IF (Size>10) OR (Size<1) THEN Size:=1;
- IF (Line>24) THEN Line:=24; { Zeile 1..24 }
- IF (Line<1) THEN Line:=1;
- IF Font=2 THEN Size:=Size*2;
- SetViewPort(0,0,GetMaxX,GetMaxY,ClipOn);
- SetColor(TxtCol);
- SetTextStyle(Font,HorizDir,Size);
- SetTextJustify(CenterText,CenterText); { Zentrieren }
- Xpos:=Succ(GetMaxX) DIV 2;
- Ypos:=Line*(GetMaxY DIV 25);
- OutTextXY(Xpos,Ypos,Text);
- END;
-
- PROCEDURE GraphikWindow; { Graphikfenster }
- VAR h:INTEGER;
- BEGIN
- SetLineStyle(SolidLn,0,NormWidth); SetColor(White);
- IF x1>x2 THEN BEGIN h:=x1; x1:=x2; x2:=h; END;
- IF y1>y2 THEN BEGIN h:=y1; y1:=y2; y2:=h; END;
- Line(x1,GetMaxY-y1,x2,GetMaxY-y1); { Rahmen }
- Line(x2,GetMaxY-y1,x2,GetMaxY-y2);
- Line(x2,GetMaxY-y2,x1,GetMaxY-y2);
- Line(x1,GetMaxY-y2,x1,GetMaxY-y1);
- Uaxmin:=x1; Uaxmax:=x2; Vaxmin:=y1; Vaxmax:=y2; { Fensterkoordinaten }
- END;
-
- PROCEDURE LinaxScale; { Hilfsroutine fuer }
- VAR x1,x2:REAL; { Xaxis und Yaxis }
- BEGIN
- IF Abs(a)<Abs(b) THEN Ex:=Exponent(b) ELSE Ex:=Exponent(a);
- x1:=a; x2:=b; dx:=0.25*EXP10(Exponent(b-a));
- ExpStrg:='0';
- IF Abs(Ex)>3 THEN BEGIN { Exponent abtrennen }
- a:=a*EXP10(-Ex); b:=b*EXP10(-Ex); dx:=dx*EXP10(-Ex);
- Str(Ex:4:0,ExpStrg); WHILE ExpStrg[1]=#32 DO Delete(ExpStrg,1,1);
- END;
- WHILE ((b-a)/dx)>=Density DO dx:=2*dx; { Skalendichte }
- IF b<a THEN dx:=-dx;
- IF a=b THEN BEGIN a:=a-dx; b:=b+dx; END;
- a:=dx*Round(a/dx); { Guenstig runden }
- b:=dx*Round(b/dx);
- IF a<b THEN BEGIN
- IF a<x1 THEN a:=a+dx; IF b>x2 THEN b:=b-dx; END
- ELSE BEGIN
- IF a>x1 THEN a:=a-dx; IF b<x2 THEN b:=b+dx;
- END;
- END;
-
- FUNCTION LOG10; { dekad. Logarithmus }
- BEGIN
- IF x<>0 THEN LOG10:=Ln(Abs(x))/Ln(10.0) ELSE LOG10:=0;
- END;
-
- PROCEDURE LogXAxis; { Log. x-Achse }
- CONST Density=10; { Skalendichte }
- VAR dn,n1,n2,n,k,u,v:INTEGER; x:REAL; S:STRING[6];
- BEGIN
- Line(Uaxmin,GetMaxY-Vaxmin,Uaxmax,GetMaxY-Vaxmin);
- u:=(Uaxmax+Uaxmin) DIV 2;
- v:=GetMaxY-(Vaxmin-3*TextHeight(XText));
- SetTextStyle(Font,HorizDir,Size);
- SetTextJustify(CenterText,CenterText);
- OutTextXY(u,v,XText); { Achsenbeschriftung }
- n1:=Trunc(LogX1); n2:=Trunc(LogX2);
- IF n1>n2 THEN BEGIN k:=n1; n1:=n2; n2:=k; END;
- dn:=1; WHILE (n2-n1) DIV dn>=Density DO dn:=Density*dn;
- IF dn=1 THEN BEGIN { Log-Skala }
- FOR n:=n1-1 TO n2+1 DO
- FOR k:=2 TO 9 DO BEGIN x:=n+LOG10(k); Xmark(x,u,3); END;
- END;
- FOR n:=n1 TO n2 DO BEGIN
- IF (dn<>1) AND ((n MOD (dn DIV 10))=0) THEN Xmark(n,u,3);
- IF (n MOD dn)=0 THEN BEGIN
- Xmark(n,u,4);
- Str(n,S);
- OutTextXY(u+TextWidth(S)*4 DIV 5,GetMaxY-Vaxmin+(TextHeight('0') DIV 2),S);
- OutTextXY(u-TextWidth('0') DIV 2,GetMaxY-Vaxmin+TextHeight('0'),'10');
- END;
- END;
- END;
-
- PROCEDURE LogYAxis; { log. y-Achse }
- CONST Density=10; { Skalendichte }
- VAR dn,n1,n2,n,k,u,v:INTEGER; y:REAL; S:STRING[6];
- BEGIN
- Line(Uaxmin,GetMaxY-Vaxmin,Uaxmin,GetMaxY-Vaxmax);
- u:=Uaxmin-3*TextHeight(YText);
- v:=(Vaxmax-Vaxmin) DIV 2;
- SetTextStyle(Font,VertDir,Size);
- SetTextJustify(CenterText,CenterText);
- OutTextXY(u,v,YText); { Achsenbeschriftung }
- n1:=Trunc(LogY1); n2:=Trunc(LogY2);
- IF n1>n2 THEN BEGIN k:=n1; n1:=n2; n2:=k; END;
- dn:=1; WHILE (n2-n1) DIV dn>=Density DO dn:=Density*dn;
- IF dn=1 THEN BEGIN { Log-Skala }
- FOR n:=n1-1 TO n2+1 DO
- FOR k:=2 TO 9 DO BEGIN y:=n+LOG10(k); Ymark(y,v,3); END;
- END;
- FOR n:=n1 TO n2 DO BEGIN
- IF (dn<>1) AND ((n MOD (dn DIV 10))=0) THEN Ymark(n,u,3);
- IF (n MOD dn)=0 THEN BEGIN
- Ymark(n,v,4);
- Str(n,S);
- OutTextXY(Uaxmin-TextHeight('0'),v-TextWidth(S)*3 DIV 4,S);
- OutTextXY(Uaxmin-TextHeight('0') DIV 2,v+TextWidth('0') DIV 2,'10');
- END;
- END;
- END;
-
- PROCEDURE OpenGraphik; { Graphik starten }
- BEGIN
- DirectVideo:=FALSE; { Graphik- und Textmode }
- OldExitProc:=ExitProc; ExitProc:=Addr(CloseGraphik);
- GraphDriver:=Detect;
- InitGraph(GraphDriver,GraphMode,'');
- ErrorCode:=GraphResult;
- IF ErrorCode<>grOk THEN BEGIN
- WriteLn('Graphics error: ',GraphErrorMsg(ErrorCode)); ReadLn;
- Halt(1);
- END;
- IF GraphDriver=7 THEN BEGIN
- Black:=0; Blue:=15; Green:=15; Cyan:=15;
- Red:=15; Magenta:=15; Brown:=15; LightGray:=15;
- DarkGray:=15; LightBlue:=15; LightGreen:=15; LightCyan:=15;
- LightRed:=15; LightMagenta:=15; Yellow:=15; White:=15;
- END;
- IF Geraet IN [Bildschirm,Drucker,Plotter] THEN ELSE Geraet:=Drucker;
- Uaxmin:=0; Uaxmax:=GetMaxX; Vaxmin:=0; Vaxmax:=GetMaxY;
- END;
-
- FUNCTION RealToString; { Reelle Zahl in }
- VAR S:strg80; Code:WORD; { handlichen String }
- BEGIN
- Str(x:16:10,S);
- WHILE S[1]=#32 DO Delete(S,1,1);
- WHILE S[Length(S)]='0' DO BEGIN Delete(S,Length(S),1); END;
- IF Pos('.',S)=Length(S) THEN Delete(S,Length(S),1);
- Val(S,x,Code); IF x=0 THEN S:='0';
- RealToString:=S;
- END;
-
- PROCEDURE Scale; { Absolute Skalierung }
- BEGIN
- u:= Uaxmin+Round((x-Xaxmin)/(Xaxmax-Xaxmin)*(Uaxmax-Uaxmin));
- v:=GetMaxY-Round((y-Yaxmin)/(Yaxmax-Yaxmin)*(Vaxmax-Vaxmin))-Vaxmin;
- END;
-
- PROCEDURE Uscale; { Benutzer- }
- VAR xx,yy:REAL; { koordinatensystem }
- CONST Tol = 0.01;
- BEGIN
- Expans:=Abs(Expans);
- xx:=Abs(x2-x1)*0.005*Expans; IF x1>x2 THEN xx:=-xx; { 1. Ausweiten }
- x1:=x1-xx; x2:=x2+xx;
- IF Abs(x2-x1)<1E-8 THEN
- BEGIN x1:=x1*(1-0.01*Expans); x2:=x2*(1+0.01*Expans); END;
- yy:=Abs(y2-y1)*0.005*Expans; IF y1>y2 THEN yy:=-yy;
- y1:=y1-yy; y2:=y2+yy;
- IF Abs(y2-y1)<1E-8 THEN
- BEGIN y1:=y1*(1-0.01*Expans); y2:=y2*(1+0.01*Expans); END;
- IF Origin THEN BEGIN { 2. Ursprung }
- IF x1<=x2 THEN BEGIN
- IF x2<0 THEN x2:=0;
- IF x1>0 THEN x1:=0; END
- ELSE BEGIN
- IF x2>0 THEN x2:=0;
- IF x1<0 THEN x1:=0;
- END;
- IF y1<=y2 THEN BEGIN
- IF y2<0 THEN y2:=0;
- IF y1>0 THEN y1:=0; END
- ELSE BEGIN
- IF y2>0 THEN y2:=0;
- IF y1<0 THEN y1:=0;
- END;
- END;
- IF AngleTrue THEN AngleTrueScale(x1,x2,y1,y2); { 3. Winkeltreue }
- IF Abs((x2-x1)/x2)<Tol THEN BEGIN { 4. Minimalausdehnung }
- IF x1<x2 THEN
- BEGIN x1:=x1*(1-Tol); x2:=x2*(1+Tol); END
- ELSE BEGIN x2:=x2*(1-Tol); x1:=x1*(1+Tol); END;
- END;
- IF Abs((y2-y1)/y2)<Tol THEN BEGIN
- IF y1<y2 THEN
- BEGIN y1:=y1*(1-Tol); y2:=y2*(1+Tol); END
- ELSE BEGIN y2:=y2*(1-Tol); y1:=y1*(1+Tol); END;
- END;
- Xaxmin:=x1; Xaxmax:=x2;
- Yaxmin:=y1; Yaxmax:=y2;
- END;
-
- PROCEDURE XAxis; { lineare x-Achse }
- VAR Xpos,Ypos:INTEGER;
- Ex,u,v,a,b,x,dx,h:REAL; E,S:strg80;
- CONST Density=6; { Skalendichte }
- BEGIN
- Line(Uaxmin,GetMaxY-Vaxmin,Uaxmax,GetMaxY-Vaxmin);
- Xpos:=(Uaxmax+Uaxmin) DIV 2;
- Ypos:=GetMaxY-(Vaxmin-3*TextHeight(XText));
- a:=x1; b:=x2; IF a>b THEN BEGIN h:=b; b:=a; a:=b; END;
- LinaxScale(x1,x2,dx,Ex,Density,E);
- IF x1>x2 THEN BEGIN h:=x1; x1:=x2; x2:=h; dx:=Abs(dx); END;
- SetTextStyle(Font,HorizDir,Size);
- SetTextJustify(CenterText,CenterText);
- IF E='0' THEN { Achsenbeschriftung }
- OutTextXY(Xpos,Ypos,XText)
- ELSE BEGIN
- u:=Xaxmin; v:=Xaxmax;
- OutTextXY(Xpos,Ypos,XText+' *E'+E);
- a:=a*EXP10(-Ex); b:=b*EXP10(-Ex); Xaxmin:=a; Xaxmax:=b;
- END;
- x:=x1; { lineare Skala }
- Xmark(x-dx/2,Xpos,3);
- REPEAT
- Xmark(x+dx/2,Xpos,3);
- Xmark(x,Xpos,3);
- S:=RealToString(x);
- Line(Xpos,GetMaxY-Vaxmin,Xpos,GetMaxY-Vaxmin-3);
- IF Length(S)<6 THEN OutTextXY(Xpos,GetMaxY-Vaxmin+TextHeight('0'),S);
- x:=x+dx;
- UNTIL (x>=b) OR (x<=a);
- IF E<>'0' THEN BEGIN Xaxmin:=u; Xaxmax:=v; END;
- END;
-
- PROCEDURE Xgrid; { Parallele zur }
- VAR u,v:INTEGER; { x-Achse }
- BEGIN
- Scale(x,0,u,v);
- IF u>Uaxmin THEN Line(u,GetMaxY-Vaxmin,u,GetMaxY-Vaxmax);
- END;
-
- PROCEDURE Xmark; { x-Achsenmarken: }
- VAR v:INTEGER; { Hilfsroutine fuer }
- BEGIN { Xaxis und LogXAxis }
- Scale(x,Yaxmin,u,v);
- IF (u>=Uaxmin) AND (u<=Uaxmax) THEN
- Line(u,GetMaxY-Vaxmin,u,GetMaxY-Vaxmin-Len);
- END;
-
- PROCEDURE YAxis; { lineare y-Achse }
- VAR Xpos,Ypos:INTEGER;
- Ex,u,v,a,b,y,dy,h:REAL; E,S:strg80;
- CONST Density=8; { Skalendichte }
- BEGIN
- Line(Uaxmin,GetMaxY-Vaxmin,Uaxmin,GetMaxY-Vaxmax);
- Xpos:=Uaxmin-3*TextHeight(YText);
- Ypos:=(Vaxmax-Vaxmin) DIV 2;
- a:=y1; b:=y2; IF a>b THEN BEGIN h:=b; b:=a; a:=b; END;
- LinaxScale(y1,y2,dy,Ex,Density,E);
- IF y1>y2 THEN BEGIN h:=y1; y1:=y2; y2:=h; dy:=Abs(dy); END;
- SetTextStyle(Font,VertDir,Size);
- SetTextJustify(CenterText,CenterText);
- IF E='0' THEN { Achsenbeschriftung }
- OutTextXY(Xpos,Ypos,YText)
- ELSE BEGIN
- u:=Yaxmin; v:=Yaxmax;
- OutTextXY(Xpos,Ypos,YText+' *E'+E);
- a:=a*EXP10(-Ex); b:=b*EXP10(-Ex); Yaxmin:=a; Yaxmax:=b;
- END;
- y:=y1; { lineare Skala }
- Ymark(y-dy/2,Ypos,3);
- REPEAT
- Ymark(y+dy/2,Ypos,3);
- S:=RealToString(y);
- Ymark(y,Ypos,3);
- IF Length(S)<6 THEN OutTextXY(Uaxmin-TextHeight('0'),Ypos,S);
- y:=y+dy;
- UNTIL (y>=b) OR (y<=a);
- IF E<>'0' THEN BEGIN Yaxmin:=u; Yaxmax:=v; END;
- END;
-
- PROCEDURE Ygrid; { Parallele zur }
- VAR u,v:INTEGER; { y-Achse }
- BEGIN
- Scale(0,y,u,v);
- IF v<GetMaxY-Vaxmin THEN Line(Uaxmin,v,Uaxmax,v);
- END;
-
- PROCEDURE Ymark; { y-Achsenmarken: }
- VAR u:INTEGER; { Hilfsroutine fuer }
- BEGIN { Yaxis und LogYAxis }
- Scale(Xaxmin,y,u,v);
- IF (v<GetMaxY-Vaxmin) AND (v>GetMaxY-Vaxmax) THEN
- Line(Uaxmin,v,Uaxmin+Len,v);
- END;
-
- END.
-