home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turbo Toolbox
/
Turbo_Toolbox.iso
/
sonderh1
/
zweidim.pas
< prev
Wrap
Pascal/Delphi Source File
|
1987-03-13
|
11KB
|
243 lines
{---------------------------------------------------------------------------}
{ Programm zur zweidimensionalen Darstellung von Matrizen }
{---------------------------------------------------------------------------}
PROGRAM ZweiDim (Input, Output);
CONST xmax = 72; { maximal (xmax+1)*(ymax+1) }
ymax = 72; { Punkte der Bildmatrix. }
TYPE xi = 1..xmax; { (xi+1)*(yi+1) Punkte }
yi = 1..ymax; { der Bildmatrix. }
bild = ARRAY[0..xmax,0..ymax] OF REAL; { die Bildmatrix. }
art = (gs,hl,zv); { Darstellungsarten. }
VAR bx: xi;
by: yi;
f: bild; { Bildmatrix }
h1, h2 : REAL; { untere und obere Intervallgrenze }
ptrinit: STRING; { Druckerinitialisierung fuer Grafik }
px, py : INTEGER; { Druckerpunkte pro Zeile, Spalte }
c : CHAR; { Index fuer Menu }
{---------------------------------------------------------------------------}
{ Darstellung einer dreidimensionalen Flaeche durch:
Druckerausgabe des Bildes f[0..bx,0..by] im Intervall z = h1 ... h2
a: mit Graustufen, Hoehenlinien oder Zufallsverfahren
px, py geben die Bildabmessungen in Druckerpunkten an
(px <= dmax, py sollte durch 8 teilbar sein)
Init wird zu Beginn jeder Druckerzeile gesendet }
PROCEDURE ZweiD (VAR f: bild; { Bildmatrix }
bx: xi; by: yi; { linke und untere Grenze des Bildes }
h1, h2: REAL; { Intervallgrenzen f. Bilderzeugung }
a: art; { Art der Darstellung }
px, py: INTEGER; { Bildabmessung in Druckerpunkte }
Init: STRING); { Initialisierung des Druckers }
CONST dmax = 960; { maximale Punktzahl pro Druckerzeile }
rmax = $FFFFFF; { Groesstmoegliche Zahl des Zufallszahlengenerators }
nh = 10; { nh + 1 Hoehenlinien im Intervall h1..h2 }
VAR db: ARRAY[1..dmax] OF BYTE; { eine Druckerzeile }
ha: ARRAY[1..dmax] OF INTEGER; { Vorgaengerzeile fuer Hoehenlinien }
m1, m2, m3: BYTE; { Punktmuster }
pb, dz, { Pixel pro Byte, Druckerzeilen }
nx, ny, { Pixel in x-, y-Richtung }
i, j, k, { Laufvariablen }
ih, iha, { Hoehe, Hoehe des Vorgaengers fuer Hoehenlinien }
x0, x1, xa, { x-Indizes der Bildmatrix }
y0, y1, { y-Indizes der Bildmatrix }
i1, i2 : INTEGER; { Indizes im Feld db fuer Graustufen }
fx, fy, fz, { Massstabsfaktoren }
xd, yd, zd, { Koordinaten der Druckerpixel }
x, y, ye, { xd-x0, yd-y0, 1-(yd-y0) }
k0, k1 : REAL; { Groessen zur Berechnung von zd }
{-------------------------------------------------------------------------}
{ Zufallszahlengenerator fuer Atari ST: }
FUNCTION Random: LONG_INTEGER;
XBios(17);
{-------------------------------------------------------------------------}
BEGIN { ZweiD }
{ Berechnung der Normierungsfaktoren fx, fy und fz
sowie der Drucker-Pixelzahlen nx und ny: }
CASE a OF
gs: BEGIN pb := 4; fz := 4/(h2-h1); END;
zv: BEGIN pb := 8; fz := rmax/(h2-h1); END;
hl: BEGIN pb := 8; fz := nh/(h2-h1); END;
END;
nx := px*pb DIV 8; ny := py*pb DIV 8;
fx := bx/nx; fy := by/ny;
dz := py DIV 8;
{ Initialisierung des Vorgaengerfeldes ha fuer Hoehenlinien: }
xd := 0.5*fx;
IF a = hl THEN
FOR i := 1 TO nx DO
BEGIN
x0 := Trunc(xd); x := xd-x0; x1 := Succ(x0); xd := xd+fx;
ha[i] := Trunc(fz*((1-x)*f[x0,by]+x*f[x1,by]-h1)+1);
END;
ReWrite(Output, 'PRN:'); { Ausgabe auf Drucker umleiten }
xa := MaxInt;
FOR j := 0 TO Pred(dz) DO { Hauptschleife ueber alle Druckerzeilen }
BEGIN
FOR i := 1 TO px DO db[i] := 0; { Druckerzeile loeschen }
{ Punktmuster fuer oberstes Bildpixel der Druckerzeile setzen: }
m1 := 64; m2 := 128; m3 := 192;
FOR k := 1 TO pb DO { Schleife ueber alle Pixel in einer Druckerzeile }
BEGIN
yd := by-(pb*j+k-0.5)*fy; xd := 0.5*fx;
y0 := Trunc(yd); y1 := Succ(y0);
y := yd-y0; ye := 1-y;
{ Initialisierung des Vorgaengerwertes iha fuer Hoehenlinien: }
IF a = hl THEN
iha := Trunc(fz*(ye*f[0,y0]+y*f[0,y1]-h1)+1);
{ Schleife ueber alle horizontal nebeneinanderliegenden Druckerpixel: }
FOR i := 1 TO nx DO
BEGIN
x0 := Trunc(xd); x := xd-x0;
{ Neues bildpixel? Wenn ja, dann Neuberechnung von k0 und k1,
sonst zd mit alten Werten von k0 und k1 berechnen }
IF x0 <> xa THEN
BEGIN
xa := x0; x1 := Succ(x0);
k0 := ye*f[x0,y0]+y*f[x0,y1]; k1 := ye*f[x1,y0]+y*f[x1,y1]-k0;
k0 := k0-h1;
END;
zd := x*k1+k0; xd:=xd+fx;
{ der weitere Ablauf unterscheidet sich je
nach Darstellungsart gs, hl oder zv: }
CASE a OF
{ Graustufen: je nach Pixelwert zd bis zu 4
Punkte in Druckerfeld db ausgeben }
gs: IF zd > 0 THEN
BEGIN
i2 := i+i; i1 := Pred(i2);
CASE Trunc(fz*zd) OF
0: db[i2] := db[i2]+m1;
1: BEGIN
db[i1] := db[i1]+m2; db[i2] := db[i2]+m1;
END;
2: BEGIN
db[i1] := db[i1]+m1; db[i2] := db[i2]+m3;
END;
3: BEGIN
db[i1] := db[i1]+m3; db[i2] := db[i2]+m3;
END;
END; { CASE Trunc }
END;
{ Zufallsverfahren: Pixelwert zd mit
Zufallswert vergleichen }
zv: IF zd > 0 THEN
IF fz*zd > Random THEN
db[i] := db[i]+m2;
{ Hoehenlinien: Pixelwert zd mit oberem und
linkem Nachbarn vergleichen }
hl: BEGIN
ih := Trunc(fz*zd+1.0);
IF ih <> iha THEN { Vergleich mit linkem Nachbarn }
IF (ih IN [1..nh]) OR (iha IN [1..nh]) THEN
db[i] := db[i] | m2; { |-Operator: bitweises Oder }
IF ih <> ha[i] THEN { Vergleich mit oberem Nachbarn }
IF (ih IN [1..nh]) OR (ha[i] IN [1..nh]) THEN
db[i] := db[i] | m2;
{ Nachbarn fuer naechsten Punkt speichern: }
iha := ih; ha[i] := ih;
END;
END; { CASE a }
END; { FOR i }
{ Punktmuster fuer naechsttiefere Pixelzeile aendern: }
IF a = gs THEN
BEGIN
m1 := m1 DIV 4; m2 := m2 DIV 4; m3 := m3 DIV 4;
END
ELSE
m2 := m2 DIV 2;
END; { FOR k }
{ Drucker initialisieren und Zeile ausgeben: }
Write(Init);
FOR i:=1 TO px DO Write(Chr(db[i]));
END; { FOR j }
Page; { Seitenvorschub }
ReWrite(Output, 'CON:'); { Ausgabe wieder auf den Bildschirm }
END; { ZweiD }
{---------------------------------------------------------------------------}
{ Erzeugung einer beispielhaften Bildmatrix: }
PROCEDURE daten (VAR bx: xi; VAR by: yi; VAR f: bild);
VAR i, j, k : INTEGER;
x, y, r, s, dx: REAL;
xx, mx, my, h : ARRAY[1..4] OF REAL;
BEGIN
WriteLn; WriteLn(' Berechnung der Bilddaten, bitte warten!');
bx := 50; by := 50; dx := 0.16;
mx[1] := 0.25*dx*bx; my[1] := 0.25*dx*by; h[1] := 11.5;
mx[2] := 0.50*dx*bx; my[2] := 0.50*dx*by; h[2] := -5.7;
mx[3] := 0.50*dx*bx; my[3] := 0.75*dx*by; h[3] := 11.3;
mx[4] := 0.75*dx*bx; my[4] := 0.50*dx*by; h[4] := 11.3;
FOR i := 0 TO bx DO
BEGIN
x := dx*i;
FOR k := 1 TO 4 DO xx[k] := Sqr(x-mx[k]);
FOR j := 0 TO by DO
BEGIN
y := dx*j; s := 0;
FOR k := 1 TO 4 DO
BEGIN
r := xx[k]+Sqr(y-my[k]);
s := s+h[k]/(1+r);
END;
f[i,j] := s;
END;
END;
END;
{---------------------------------------------------------------------------}
BEGIN { ZweiDim }
daten(bx, by, f);
{ die Beispiele werden mit horizontal 640
und vertikal 576 Druckerpunkten gerechnet }
px := 640; py := 576;
{ Druckerinitialisierung: Zeilenvorschub um 24/216 Zoll,
Druckkopf an linken Rand,
640 Punkte pro Zeile }
ptrinit := Concat(#27, 'J', #24,
#13,
#27, '*', #4, Chr(px MOD 256), Chr(px DIV 256));
{ Schleife fuer das Menu, Bildschirm loeschen, Cursor ein: }
REPEAT
WriteLn(#27, 'e', #27, 'e');
WriteLn(' Druckerausgabe:');
WriteLn;
WriteLn(' G = Graustufen');
WriteLn(' H = Hoehenlinien');
WriteLn(' Z = Zufallsverfahren');
WriteLn;
WriteLn(' E = Ende');
WriteLn; Write(' ');
Read(c);
IF c IN ['G','H','Z','g','h','z'] THEN
BEGIN
WriteLn; WriteLn;
Write(' untere und obere Grenze h1 < h2 : ');
Read(h1, h2);
IF h1 < h2 THEN
{ Aufruf der Grafik-Prozedur mit entsprechenden Parametern: }
CASE c OF
'G', 'g': ZweiD(f, bx, by, h1, h2, gs, px, py, ptrinit);
'H', 'h': ZweiD(f, bx, by, h1, h2, hl, px, py, ptrinit);
'Z', 'z': ZweiD(f, bx, by, h1, h2, zv, px, py, ptrinit);
END;
END;
UNTIL c IN ['E','e'];
END.