home *** CD-ROM | disk | FTP | other *** search
- {---------------------------------------------------------------------------}
- { 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.