home *** CD-ROM | disk | FTP | other *** search
- {---------------------------------------------------------}
- { Programm zur dreidimensionalen Darstellung von Matrizen }
- { aus PASCAL 2/87, angepaßt an Turbo Pascal 4.0 }
- {---------------------------------------------------------}
- PROGRAM DREI_DIM;
- (* Compiler/Linker in den 2 Units *)
- USES Crt, Graph; (* benötigte Routinen suchen lassen *)
-
- CONST NN = 36; { MAXIMAL (2*NN+1)*(2*NN+1) BILDPUNKTE }
-
- TYPE BILD = ARRAY[-NN..NN,-NN..NN] OF REAL;
- INDEX = 1..NN;
-
- VAR N: INDEX; { (2*N+1)*(2*N+1) BILDPUNKTE }
- DX: REAL; { ACHSENINTERVALL }
- F: BILD; { BILDMATRIX }
- ALFA, BETA: REAL; { DREH- UND NEIGUNGSWINKEL }
- (* die für "InitGraph" notwendigen Variablen: *)
- GraphDriver, GraphMode, GraphCode : INTEGER;
- {=========================================================}
- { DREIDIMENSIONALE DARSTELLUNG MIT DER PROJEKTIONSFORMEL:
- X' = X*COS(ALFA)-Y*SIN(ALFA)
- Y' = [X*SIN(ALFA)+Y*COS(ALFA)]*COS(BETA)+Z*SIN(BETA)
- ALFA, BETA: DREH- UND NEIGUNGSWINKEL
- DX: INTERVALL, N: MAXIMALINDEX DES FELDES F[-N..N,-N..N]
- I * DX IST DIE X- UND J * DX DIE Y-KOORDINATE DES
- BILDPUNKTES Z=F[I,J]
- AUTO = TRUE: AUTOMATISCHE SKALIERUNG DER Z-ACHSE }
-
- PROCEDURE DREID (ALFA, BETA, DX: REAL; N: INDEX;
- VAR F: BILD; AUTO: BOOLEAN);
-
- CONST LINKS = 0; OBEN = 0; (* RECHST u. UNTEN siehe VAR *)
-
- VAR I, J, IXMIN, IYMIN, IXMAX, IYMAX: INTEGER;
- SA, CA, SB, CB, CC, SC,
- FX, FY, XMIN, XMAX, YMIN, YMAX, X, Y: REAL;
- (* um die aktuelle Auflösung nutzen zu können, werden
- später initialisierte Variablen als Grenzen verw.: *)
- RECHTS, UNTEN: INTEGER;
- {-------------------------------------------------------}
- { ZEICHNET EINE ZEILE VON VIERECKEN AUF DEN BILDSCHIRM }
- PROCEDURE VIERECK (NL, NR, DI: INTEGER);
-
- VAR IX, IY, MIN, MAX: INTEGER;
- JSA, JCC: REAL;
- P: ARRAY[0..9] OF INTEGER; { KOORDINATEN DER ECKEN }
-
- BEGIN
- JSA := J * SA; JCC := J * CC; I := NL;
- { ERSTEN 2 ECKEN DES ERSTEN VIERECKS WERDEN BERECHNEN: }
- X := I*CA-JSA; P[2] := ROUND(X-XMIN)+IXMIN;
- Y := I*SC+JCC+F[I,J]*SB; P[3] := ROUND(Y-YMIN)+IYMIN;
- X := X+SA; P[4] := ROUND(X-XMIN)+IXMIN;
- Y := Y-CC+(F[I,J-1]-F[I,J])*SB;
- P[5] := ROUND(Y-YMIN)+IYMIN;
- { DAS FOLGENDE VIERECK ERGIBT SICH AUS 2 ECKEN DES
- VORHERGEHENDEN VIERECKS UND 2 NEUBERECHNETEN ECKEN }
- REPEAT
- I := I+DI; IX := P[2]; P[0] := IX; P[8] := IX;
- IX := 0; IY := P[3]; P[1] := IY; P[9] := IY;
- MIN := IY; MAX := IY; P[6] := P[4]; IY := P[5];
- P[7] := IY;
- IF IY < MIN THEN MIN := IY
- ELSE IF IY > MAX THEN MAX := IY;
- X := I*CA-JSA; P[2] := ROUND(X-XMIN)+IXMIN;
- Y := I*SC+JCC+F[I,J]*SB; IY := ROUND(Y-YMIN)+IYMIN;
- P[3] := IY;
- IF IY < MIN THEN MIN := IY
- ELSE IF IY > MAX THEN MAX:=IY;
- X := X+SA; P[4] := ROUND(X-XMIN)+IXMIN;
- Y := Y-CC+(F[I,J-1]-F[I,J])*SB;
- IY := ROUND(Y-YMIN)+IYMIN; P[5] := IY;
- IF IY < MIN THEN MIN := IY
- ELSE IF IY > MAX THEN MAX:=IY;
- (* das Zeichnen eines Vierecks, gefüllt mit der
- Hintergrundfarbe, ist mit Turbo viel einfacher: *)
- SetFillStyle(SolidFill,0); FillPoly(5,P);
- UNTIL I = NR;
- END;
- {-------------------------------------------------------}
- BEGIN
- (* die aktuelle Auflösung der Grafik-Karte ermitteln: *)
- RECHTS := GetMaxX; UNTEN := GetMaxY;
- { UMRANDUNG ZEICHNEN: }
- IXMIN := LINKS+3; IXMAX := RECHTS-3;
- IYMIN := UNTEN-3; IYMAX := OBEN+3;
- LINE(LINKS,OBEN,LINKS,UNTEN);
- LINE(LINKS,UNTEN,RECHTS,UNTEN);
- LINE(RECHTS,UNTEN,RECHTS,OBEN);
- LINE(RECHTS,OBEN,LINKS,OBEN);
- { KONSTANTEN FUER PROJEKTIONSFORMEL BERECHNEN }
- SA := ALFA*PI/180; CA := DX*COS(SA); SA := DX*SIN(SA);
- SB := BETA*PI/180; CB := COS(SB); SB := SIN(SB);
- { AUTOSKALIERUNG: HOEHE AUF SEITENLAENGE }
- IF AUTO THEN BEGIN { DER BILDEBENE NORMIEREN }
- XMIN := F[0,0]; XMAX := XMIN;
- FOR I:= -N TO N DO
- FOR J := -N TO N DO BEGIN
- X := F[I,J];
- IF X < XMIN THEN XMIN := X
- ELSE IF X > XMAX THEN XMAX := X;
- END;
- IF XMAX <> XMIN THEN
- SB := 2 * N * DX *SB / (XMAX - XMIN);
- END;
- { MINIMALE UND MAXIMALE X'-KOORDINATE DER PROJEKTION }
- FX := N*CA; FY := N*SA; XMIN := -FX-FY; XMAX := XMIN;
- X := FX-FY;
- IF X < XMIN THEN XMIN := X;
- IF X > XMAX THEN XMAX := X;
- X := FY-FX;
- IF X < XMIN THEN XMIN := X;
- IF X > XMAX THEN XMAX := X;
- X := FX+FY;
- IF X < XMIN THEN XMIN := X;
- IF X > XMAX THEN XMAX := X;
- { MINIMALE UND MAXIMALE Y'-KOORDINATE DER PROJEKTION }
- YMIN := F[0,0]*SB; YMAX := YMIN; CC := CA*CB; SC:= SA*CB;
- FOR J := N DOWNTO -N DO BEGIN
- FY := J * CC - N * SC;
- FOR I := -N TO N DO BEGIN
- Y := FY + F[I,J] * SB; FY := FY + SC;
- IF Y < YMIN THEN YMIN := Y
- ELSE IF Y > YMAX THEN YMAX := Y;
- END;
- END;
- { NORMIERUNGSFAKTOREN FUER X- UND Y-
- ACHSE BERECHNEN, KONSTANTEN NORMIEREN }
- FX := (IXMAX-IXMIN)/(XMAX-XMIN); XMIN := XMIN * FX;
- FY := (IYMAX-IYMIN)/(YMAX-YMIN); YMIN := YMIN * FY;
- SA := SA * FX; CA := CA * FX; CC := CC * FY;
- SC := SC * FY; SB := SB * FY;
- { 3-D AUSGABE AUF BILDSCHIRM }
- IF CA > 0 THEN
- FOR J := N DOWNTO -N+1 DO
- IF SA > 0 THEN VIERECK(N,-N,-1) ELSE VIERECK(-N,N,1)
- ELSE
- FOR J := -N + 1 TO N DO
- IF SA > 0 THEN VIERECK(N,-N,-1) ELSE VIERECK(-N,N,1);
- END;
- {=========================================================}
- { ERZEUGUNG DER AUSGABEDATEN, HIER SIN(X)/X - FUNKTION }
- PROCEDURE DATEN (VAR N: INDEX; VAR DX: REAL; VAR F: BILD);
- VAR I, J: INTEGER; X, Y: REAL;
- BEGIN
- WriteLn; WriteLn;
- WriteLn(' BERECHNUNG DER BILDDATEN, BITTE WARTEN!');
- N := 18; DX := 0.35;
- FOR I := -N TO N DO BEGIN
- X := 1.25 * DX * I;
- IF X = 0 THEN X := 1 ELSE X := SIN(X) / X;
- FOR J := -N TO N DO BEGIN
- Y := DX * J;
- IF Y = 0 THEN Y := 1 ELSE Y := SIN(Y) / Y;
- F[I,J] := X * Y;
- END;
- END;
- END;
- {=========================================================}
- BEGIN
- DATEN(N, DX, F);
- (* Initialisierung der Grafik durch automatische Er-
- kennung der Karte (s. Apfelmännchen): *)
- GraphDriver := Detect;
- InitGraph(GraphDriver,GraphMode,'');
- GraphCode := GraphResult;
- IF GraphCode <> grOk THEN BEGIN
- WriteLn('Grafik-Fehler Nr. ',GraphCode);
- WriteLn('Programm abgebrochen...'); Halt;
- END;
- (* Linienart und Farbe festlegen: *)
- SetLineStyle(SolidLn,0,NormWidth); SetColor(1);
- REPEAT
- (* für folgenden Dialog wieder in den Textmode gehen: *)
- RestoreCrtMode;
- WRITELN('DREH- UND NEIGUNGSWINKEL ALFA, BETA EINGEBEN',
- ' (ABBRUCH, WENN BETA = 0)');
- WRITELN; WRITE(' '); READ(ALFA, BETA);
- IF BETA <> 0 THEN BEGIN
- (* den von "InitGraph" ermittelten Grafik-Modus
- zum Zeichnen wieder aktivieren: *)
- SetGraphMode(GraphMode);
- DREID(ALFA, BETA, DX, N, F, TRUE);
- REPEAT UNTIL KEYPRESSED;
- END;
- UNTIL BETA = 0;
- CloseGraph; (* ... und die Grafik beenden ! *)
- END.
-