home *** CD-ROM | disk | FTP | other *** search
- UNIT PLGRAPH;
- (* Umsetzung der UNIT PGraph aus TOOLBOX 12/88 für Plotter mit HPGL *)
- (* es wurde auf eine größtmögliche Befehlsgleichheit geachtet *)
- (* erfordert die UNIT HPGL *)
- (* Compiler : Turbo-Pascal 5.0
- Pgm.Vers.: 1.0.f
- Stand : 01.05.89 *)
-
- INTERFACE
-
- USES HPGL;
-
- CONST
- {$IFDEF CPU87} MaxInt=2147483647; {$ENDIF}
- nmax=200;
- type
- {$IFDEF CPU87} real=extended; {$ELSE}
- double=real; single=real; extended=real; comp=real; {$ENDIF}
- Vektor = array[1..nmax] of real;
- (*-----------------------------------------------*)
- PROCEDURE AngleTrueScale(VAR x1,x2,y1,y2:real);
- 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 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);
- 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(VAR x1,x2,y1,y2:real);
- { Winkeltreue Skalierung }
- VAR C,dx,dy,xx,yy,xm,ym,F:real; Xasp,Yasp:word;
- BEGIN
- F:= (ABS(UaxMin-UaxMax)/ABS(VaxMin-VaxMax));
- 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;
- (*-----------------------------------------------*)
- PROCEDURE Curve(VAR x,y:Vektor; n,Lintyp,Thickness,Color:word);
- { Polygonzug }
- VAR i,u1,v1,u2,v2:integer;
- BEGIN
- P_SetLineStyle (Lintyp, Thickness, 0);
- (* ^ statt der Liniendicke wird hier die Wiederholschrittweite def. !!! *)
- P_SetColor (Color);
- Scale(x[1],y[1],u1,v1);
- for i:=2 to n do BEGIN
- Scale(x[i],y[i],u2,v2); P_Line(u1,v1,u2,v2);
- u1:=u2; v1:=v2;
- END;
- END;
- (*-----------------------------------------------*)
- PROCEDURE Curvex(VAR x,y:Vektor; n:word; Color:byte);
- { Punkte auftragen }
- VAR i,u,v:integer;
- BEGIN
- for i:=1 to n do BEGIN
- Scale(x[i],y[i],u,v); P_PutPixel(u,v,Color);
- END;
- END;
- (*-----------------------------------------------*)
- FUNCTION EXP10(x:real):real;
- 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(x:real):integer;
- { Groessenordnung einer Zahl }
- VAR EX,S:string[80]; n,code:integer;
- BEGIN
- STR(x,S); EX:=COPY(S,POS('E',S)+1,Length(S));
- VAL(EX,n,code); Exponent:=n;
- END;
- (*-----------------------------------------------*)
- PROCEDURE Extrema(z:Vektor; n:word; VAR zmin,zmax:real);
- { Maximum und Minimum des Vektors z[1..n] }
- VAR i:word;
- 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 GraphikWindow(x1,x2,y1,y2:integer);
- { Graphikfenster }
- VAR h:integer;
- BEGIN
- P_SetColor (Black);
- if x1>x2 then BEGIN h:=x1; x1:=x2; x2:=h; END;
- if y1>y2 then BEGIN h:=y1; y1:=y2; y2:=h; END;
- P_Line(x1, y1, x2, y1);
- P_Line(x2, y1, x2, y2);
- P_Line(x2, y2, x1, y2);
- P_Line(x1, y2, x1, y1);
- Uaxmin:=x1; Uaxmax:=x2; Vaxmin:=y1; Vaxmax:=y2; { Fensterkoordinaten }
- END;
- (*-----------------------------------------------*)
- PROCEDURE LinaxScale(VAR a,b,dx,Ex:real; Density:byte; VAR ExpStrg:strg80);
- { Hilfsroutine fuer Xaxis und Yaxis }
- VAR x1,x2:real;
- 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(x:real):real;
- { dekad. Logarithmus }
- BEGIN
- IF x<>0 THEN LOG10 := LN (ABS(x)) / LN(10.0) ELSE LOG10 := 0;
- END;
- (*-----------------------------------------------*)
- PROCEDURE LogXAxis(LogX1,LogX2:real; XText:strg80; Font,Size:word);
- { Log. x-Achse } (* ^ mm *)
- CONST Density=10; { Skalendichte }
- VAR dn,n1,n2,n,k,u,v:integer; x:real; S:string[6];
- PSize : REAL;
- BEGIN
- P_Line(Uaxmin, Vaxmin,Uaxmax, Vaxmin);
- PSize := Size / 10; (* Textstyle (SI) erfordert Einheit 'cm' ! *)
- u := (Uaxmax+Uaxmin) div 2;
- v := (Vaxmin - ROUND (5 * Size));
- P_SetTextStyle (Font, P_HorizDir, PSize);
- P_OutTextXY(u, v, XText);
-
- 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
- for n:=n1-1 to n2+1 do
- for k:=2 to 9 do BEGIN x:=n+LOG10(k); Xmark(x,u,2); END;
- END;
-
- for n:=n1 to n2 do BEGIN
-
- IF (dn DIV 10 <> 0) THEN
- if (dn<>1) and ((n mod (dn div 10))=0) then Xmark(n,u,2);
- if (n mod dn)=0 then BEGIN
- Xmark(n,u,4);
- STR(n,S);
- P_OutTextXY (u + ROUND (8 * PSize), Vaxmin - (ROUND (45 * PSize)) DIV 2, S);
- P_OutTextXY (u - (ROUND (15 * PSize)) DIV 2, Vaxmin - ROUND (30 * PSize), '10');
- END;
- END;
- END;
- (*-----------------------------------------------*)
- PROCEDURE LogYAxis(LogY1,LogY2:real; YText:strg80; Font,Size:word);
- { log. y-Achse }
- CONST Density=10;
- VAR dn,n1,n2,n,k,u,v:integer; y:real; S:string[6];
- PSize : REAL;
- BEGIN
- P_Line(Uaxmin, Vaxmin, Uaxmin, Vaxmax);
- PSize := Size / 10; (* Textstyle (SI) erfordert Einheit 'cm' ! *)
- v := (Vaxmax+Vaxmin) div 2;
- u := (Uaxmin - ROUND (5 * Size));
- P_SetTextStyle (Font, P_VertDir, PSize);
- P_OutTextXY (u, v, YText);
-
- 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
- for n:=n1-1 to n2+1 do
- for k:=2 to 9 do BEGIN y:=n+LOG10(k); Ymark(y,v,2); END;
- END;
- for n:=n1 to n2 do BEGIN
- IF (dn DIV 10 <> 0) THEN
- if (dn<>1) and ((n mod (dn div 10))=0) then Ymark(n,u,2);
- if (n mod dn)=0 then BEGIN
- Ymark(n,v,4);
- STR(n,S);
- P_OutTextXY (Uaxmin - ROUND (25 * PSize), v + Round (PSize), S);
- P_OutTextXY (Uaxmin - ROUND (25 * PSize) DIV 2, v - (Round (20 * PSize)) DIV 2, '10');
- END;
- END;
- END;
- (*-----------------------------------------------*)
- FUNCTION RealToString(x:real):strg80;
- { Reelle Zahl in handlichen String }
- VAR S:strg80; Code:word;
-
- 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(x,y:real; VAR u,v:integer);
- { Absolute Skalierung }
- BEGIN
- u:= Uaxmin+ROUND((x-Xaxmin)/(Xaxmax-Xaxmin)*(Uaxmax-Uaxmin));
- v:= VaxMin + ROUND((y-Yaxmin)/(Yaxmax-Yaxmin)*(Vaxmax-Vaxmin));
- END;
- (*-----------------------------------------------*)
- PROCEDURE UScale(VAR X1,X2,Y1,Y2:real; Origin,AngleTrue:boolean; Expans:real);
- { Benutzer-Koordinatensystem }
- VAR xx,yy:real;
- CONST Tol = 0.01;
- ExpFaktor = 10; (* zur Kompatibilität mit UNIT PGraph *)
-
- BEGIN
- Expans:= ExpFaktor * ABS(Expans); (* ! *)
- (* damit bei gleichem Parameter in etwa gleiches Koordinatensystem ! *)
-
- xx:=ABS(x2-x1)*0.005*Expans; if x1>x2 then xx:=-xx;
- 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);
- if ABS((X2-X1)/X2)<Tol then BEGIN
- 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(x1,x2:real; XText:strg80; Font,Size:word);
- VAR Xpos,Ypos:integer;
- Ex,U,V,a,b,x,dx,h:real; E,S:strg80;
- PSize : REAL;
- CONST Density=6;
- BEGIN
- P_Line(Uaxmin, Vaxmin,Uaxmax, Vaxmin);
- PSize := Size / 10; (* Textstyle (SI) erfordert Einheit 'cm' ! *)
- XPos := (Uaxmax+Uaxmin) div 2; (* - Round (10.0 * PSize); *)
- YPos := (Vaxmin - ROUND (5 * Size));
- 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;
- P_SetTextStyle (Font, P_HorizDir, PSize);
-
- if E='0' then
- P_OutTextXY (Xpos,Ypos,XText)
- else BEGIN
- U:=Xaxmin; V:=XaxMax;
- P_OutTextXY (Xpos, Ypos, XText+' *E'+E);
- a:=a*EXP10(-Ex); b:=b*EXP10(-Ex); Xaxmin:=a; Xaxmax:=b;
- END;
-
- x:=x1;
- Xmark(x-dx/2,xpos,2);
-
- repeat
- Xmark(x+dx/2,xpos,2);
- Xmark(x,xpos,2);
- S:=RealToString(x);
- P_Line (Xpos, Vaxmin, Xpos, Vaxmin-2);
- if Length(S)<6 then P_OutTextXY (Xpos, Vaxmin - ROUND (25 * PSize), S);
- x:=x+dx;
- until (x>=b) or (x<=a);
- if E<>'0' then BEGIN Xaxmin:=U; XaxMax:=V; END;
- END;
- (*-----------------------------------------------*)
- PROCEDURE Xgrid(x:real);
- { Parallele zur x-Achse }
- VAR u,v:integer;
- BEGIN
- Scale(x,0,u,v);
- if u > Uaxmin then P_Line(u, Vaxmin, u, Vaxmax);
- END;
- (*-----------------------------------------------*)
- PROCEDURE Xmark(x:real; VAR u:integer; Len:byte);
- { x-Achsenmarken: }
- VAR v:integer;
- BEGIN
- Scale(x,Yaxmin,u,v);
- if (u>=UaxMin) and (u<=UaxMax) then
- P_Line(u, Vaxmin, u, Vaxmin + Len);
- END;
- (*-----------------------------------------------*)
- PROCEDURE YAxis(y1,y2:real; YText:strg80; Font,Size:word);
- { lineare y-Achse }
- VAR Xpos,Ypos:integer;
- Ex,U,V,a,b,y,dy,h:real; E,S:strg80;
- PSize : REAL;
- CONST Density=8;
- BEGIN
- P_Line(Uaxmin, Vaxmin, Uaxmin, Vaxmax);
- PSize := Size / 10; (* Textstyle (SI) erfordert Einheit 'cm' ! *)
- YPos := (Vaxmax+Vaxmin) div 2;
- XPos := (Uaxmin - ROUND (5 * Size));
- 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;
- P_SetTextStyle (Font, P_VertDir, PSize);
- if E='0' then
- P_OutTextXY (Xpos, Ypos, YText)
- else BEGIN
- U:=Yaxmin; V:=YaxMax;
- P_OutTextXY (Xpos, Ypos, YText+' *E'+E);
- a:=a*EXP10(-Ex); b:=b*EXP10(-Ex); Yaxmin:=a; Yaxmax:=b;
- END;
-
- y:=y1;
- Ymark(y-dy/2,ypos,2);
- repeat
- Ymark(y+dy/2,ypos,2);
- S:=RealToString(y);
- Ymark(y,ypos,2);
- P_Line (UaXmin, YPos, UaXmin - 2, YPos);
- if Length(S)<6 then P_OutTextXY (Uaxmin - ROUND (25 * PSize), YPos, S);
- y:=y+dy;
- until (y>=b) or (y<=a);
- if E<>'0' then BEGIN Yaxmin:=U; YaxMax:=V; END;
- END;
- (*-----------------------------------------------*)
- PROCEDURE Ygrid(y:real);
- { Parallele zur y-Achse }
- VAR u,v:integer;
- BEGIN
- Scale(0,y,u,v);
- if v > Vaxmin then P_Line (Uaxmin, v, Uaxmax, v);
- END;
- (*-----------------------------------------------*)
- PROCEDURE Ymark(y:real; VAR v:integer; Len:byte);
- { y-Achsenmarken: }
-
- VAR u:integer;
- BEGIN
- Scale(Xaxmin,y,u,v);
- if (v > Vaxmin) and (v < Vaxmax) then
- P_Line (Uaxmin, v, Uaxmin+Len, v);
- END;
- (*-----------------------------------------------*)
- (*-----------------------------------------------*)
- END.