home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* BROWN.PAS *)
- (* Simulation der Brownschen Molekularbewegung *)
- (* Man kann im Hauptprogramm zwischen der stochastischen *)
- (* und der deterministischen Variante wählen - *)
- (* siehe Prozeduren: stochastisch & deterministisch *)
- (* Abbruch mit Escape. *)
- (* (c) 1993 Dr.Lothar Wenzel & DMV-Verlag *)
- (* ------------------------------------------------------ *)
- PROGRAM Brown;
-
- USES
- Graph, Crt;
-
- CONST
- X_Richtung = 200; (* Grafikkoordinaten *)
- Y_Richtung = 200;
- X_H_Richtung = 100;
- X_Position = 10;
- Y_Position = 20;
-
- X_Bild = 639;
- Y_Bild = 349;
-
- Gesamtzahl = 70; (* Gesamtzahl der Moleküle *)
- Loch_Zahl = 4; (* # Löcher in der Wand *)
- Farbe_1 = White;
- Farbe_2 = Yellow;
- Farbe_3 = LightRed;
- Untergrund = Black;
-
- Auswahl = 60;
- Auswahl_2 = 30;
- Tiefe_1 = 180;
- Tiefe_2 = 190;
- Oben = 196; (* Fadenkreuz *)
- Unten = 154;
- Rechts = 446;
- Links = 404;
- Radius = 3;
-
-
- TYPE
- Punkte_X = ARRAY [1..Gesamtzahl] OF WORD;
- Punkte_Y = ARRAY [1..Gesamtzahl] OF WORD;
- Richtung_X = ARRAY [1..Gesamtzahl] OF INTEGER;
- Richtung_Y = ARRAY [1..Gesamtzahl] OF INTEGER;
-
-
- VAR
- Ort_X : ^Punkte_X; (* Koordinaten der Punkte *)
- Ort_Y : ^Punkte_Y;
- Ort_X_Alt : ^Punkte_X;
- Ort_Y_Alt : ^Punkte_Y;
- Farben : ^Punkte_X;
- Faden_X : INTEGER; (* Koordinaten äußeres Feld *)
- Faden_Y : INTEGER;
- Flug_X : ^Richtung_X; (* Flugrichtung beim *)
- Flug_Y : ^Richtung_Y; (* deterministischen Modell *)
-
-
- PROCEDURE Graph_Init;
- (* Initialisierung des Grafik-Systems *)
- VAR
- Gd, Gm : INTEGER;
- BEGIN
- Gd := Detect;
- InitGraph(Gd, Gm, 'C:\TP');
- IF GraphResult <> grOk THEN Halt(1);
- END;
-
- PROCEDURE Start;
- (* Aufbau des Startbildschirms *)
- VAR
- Index : INTEGER;
- Markierung : WORD;
- BEGIN
- Faden_X := 425;
- Faden_Y := 175;
- New(Ort_X);
- New(Ort_Y);
- New(Ort_X_Alt);
- New(Ort_Y_Alt);
- New(Farben);
- New(Flug_X);
- New(Flug_Y);
-
- SetColor(Farbe_3);
- Rectangle(X_Position, Y_Position,
- X_Position+X_Richtung+1, Y_Position+Y_Richtung+1);
- SetColor(White);
- OutTextXY(360, 140, 'Äußeres Kraftfeld');
- Rectangle(400, 150, 450, 200);
- Line(400, 175, 450, 175);
- Line(425, 150, 425, 200);
- Circle(Faden_X,Faden_Y, 3);
- SetColor(LightBlue);
- Rectangle(0, 0, X_Bild, Y_Bild);
- Rectangle(2, 2, X_Bild-2, Y_Bild-2);
- OutTextXY(X_Position, Y_Position-10,
- ' Ablauf der Simaulation');
- FOR Index := 1 TO Gesamtzahl DO BEGIN
- Ort_X^[Index] := 100+Random(10);
- Ort_Y^[Index] := Tiefe_1-160+Random(10);
- IF Ort_X^[Index] < X_H_Richtung THEN
- Markierung := Farbe_1
- ELSE
- Markierung := Farbe_2;
- Markierung := 1+(Index MOD 15);
- PutPixel(1+X_Position+X_Richtung-Ort_X^[Index],
- 1+Y_Position+Y_Richtung-Ort_Y^[Index], Markierung);
- Farben^[Index] := Markierung;
- IF Index = 1 THEN
- Flug_X^[Index] := 1
- ELSE
- Flug_X^[Index] := -1;
- IF Index = 1 THEN
- Flug_Y^[Index] := 1
- ELSE
- Flug_Y^[Index] := -1;
- END;
- END;
-
- PROCEDURE Trichter;
- (* Aufbau der zusätzlichen Wände mit Löchern *)
- VAR
- Alt_Farbe : WORD;
- i, j : INTEGER;
- BEGIN
- Alt_Farbe := GetColor;
- SetColor(Farbe_3);
-
- (* Weitere Schikanen:
- FOR i := 0 TO 10 DO BEGIN
- FOR j := 1 TO 10 DO BEGIN
- Putpixel(10*I+J+X_POSITION,10*I+Y_POSITION,FARBE_3);
- putpixel(X_RICHTUNG-10*I-J+X_POSITION,10*I+Y_POSITION,FARBE_3);
- end;
- end;
- *)
-
- Rectangle(70,70,130,130);
- SetColor(Black);
-
- { Löcher in den Innenwänden }
- FOR I:=1 TO Loch_Zahl DO
- Rectangle(60+Random(80),80+Random(40),60+Random(80),80+Random(40));
- SetColor(Alt_Farbe);
- END;
-
-
- { Löschen der alten Konstellation }
- PROCEDURE Loeschen;
- VAR
- INDEX : INTEGER;
-
- BEGIN
- FOR INDEX:=1 TO Gesamtzahl DO
- BEGIN
- PutPixel(1+X_Position+X_Richtung-Ort_X_Alt^[INDEX],
- 1+Y_Position+Y_Richtung-Ort_Y_Alt^[INDEX],Untergrund);
- END;
- END;
-
- { Auswertung der Tastenbetätigung für äußeres Feld }
- PROCEDURE Tasten_Druck;
- VAR
- Taste1,Taste2 : CHAR;
- Faden_X_Alt : INTEGER;
- Faden_Y_Alt : INTEGER;
- BEGIN
- Faden_X_Alt := Faden_X;
- Faden_Y_Alt := Faden_Y;
- Taste1 := ReadKey;
- IF Taste1 = #27 THEN Halt;
- IF Ord(Taste1)=0 THEN Taste2:=ReadKey;
- IF Ord(Taste1)=0 THEN BEGIN
- IF (Ord(Taste2)=80) AND (Faden_Y<Oben) THEN BEGIN
- Faden_Y:=Succ(Faden_Y);
- END;
-
- IF (Ord(Taste2)=72) AND (Faden_Y>Unten) THEN BEGIN
- Faden_Y:=Pred(Faden_Y);
- END;
-
- IF (Ord(Taste2)=75) AND (Faden_X>Links) THEN BEGIN
- Faden_X:=Pred(Faden_X);
- END;
- IF (Ord(Taste2)=77) AND (Faden_X<Rechts) THEN BEGIN
- Faden_X:=Succ(Faden_X);
- END;
-
- SetColor(Black);
- Circle(Faden_X_Alt,Faden_Y_Alt,Radius);
- SetColor(Yellow);
- Circle(Faden_X,Faden_Y,Radius);
- SetColor(White);
- Line(400,175,450,175);
- Line(425,150,425,200);
- END;
- END;
-
-
- { Simulation der stochastischen Molekülwanderung }
- PROCEDURE Stochastisch;
- VAR
- INDEX : INTEGER;
- Richtung : INTEGER;
- Lambda1 : REAL;
- Lambda2 : REAL;
- Alt_Farbe : WORD;
-
- { Zur Beschleunigung werden gleichzeitig x- und
- y-Richtung bearbeitet -> 8er Nachbarschaft }
- BEGIN
- Ort_X_Alt^ := Ort_X^;
- Ort_Y_Alt^ := Ort_Y^;
- Lambda1 := (Faden_X-425)/Auswahl_2;
- Lambda2 := (Faden_Y-175)/Auswahl_2;
- FOR INDEX := 1 TO Gesamtzahl DO BEGIN
- Richtung := Random(Auswahl)-Auswahl_2;
- IF Richtung >= Auswahl*Lambda1 THEN BEGIN
- IF GetPixel(1+X_Position+X_Richtung-Ort_X^[INDEX]-1,
- 1+Y_Position+Y_Richtung-Ort_Y^[INDEX])
- <>Farbe_3 THEN
- Ort_X^[INDEX] := Succ(Ort_X^[INDEX]);
- END ELSE IF GetPixel(1+X_Position+X_Richtung-Ort_X^[INDEX]+1,
- 1+Y_Position+Y_Richtung-Ort_Y^[INDEX])
- <> Farbe_3 THEN
- Ort_X^[INDEX] := Pred(Ort_X^[INDEX]);
- Richtung := Random(Auswahl)-Auswahl_2;
-
- IF Richtung >= Auswahl*Lambda2 THEN BEGIN
- IF Ort_Y^[INDEX] < Y_Richtung THEN
- IF GetPixel(1+X_Position+X_Richtung-Ort_X^[INDEX],
- 1+Y_Position+Y_Richtung-Ort_Y^[INDEX]-1)
- <> Farbe_3 THEN
- Ort_Y^[INDEX]:=Succ(Ort_Y^[INDEX]);
- END ELSE IF Ort_Y^[INDEX] > 1 THEN
- IF GetPixel(1+X_Position+X_Richtung-Ort_X^[INDEX],
- 1+Y_Position+Y_Richtung-Ort_Y^[INDEX]+1)
- <> Farbe_3 THEN
- Ort_Y^[INDEX]:=Pred(Ort_Y^[INDEX]);
- END;
- END;
-
- { Simulation der deterministischen Molekülwanderung }
- { Kraftfeld hier ohne Bedeutung }
- { Es werden Kollisionen der Moleküle berücksichtigt }
- PROCEDURE Deterministisch;
- VAR
- INDEX : INTEGER;
- Richtung : INTEGER;
- Lambda1 : REAL;
- Lambda2 : REAL;
- Alt_Farbe : WORD;
- BEGIN
- Ort_X_Alt^ := Ort_X^;
- Ort_Y_Alt^ := Ort_Y^;
- FOR INDEX := 1 TO Gesamtzahl DO BEGIN
- Richtung := Flug_X^[INDEX];
- BEGIN
- IF GetPixel(1+X_Position+X_Richtung-Ort_X_Alt^[INDEX]-Richtung,
- 1+Y_Position+Y_Richtung-Ort_Y_Alt^[INDEX])
- =Black THEN
- Ort_X^[INDEX]:=Ort_X^[INDEX]+Richtung
- ELSE
- BEGIN
- Richtung:=-Richtung;
- END;
- END;
- Flug_X^[INDEX]:=Richtung;
- Richtung:=Flug_Y^[INDEX];
- BEGIN
- IF GetPixel(1+X_Position+X_Richtung-Ort_X^[INDEX],
- 1+Y_Position+Y_Richtung-Ort_Y^[INDEX]-Richtung)
- =Black THEN
- Ort_Y^[INDEX]:=Ort_Y^[INDEX]+Richtung
- ELSE
- BEGIN
- Richtung:=-Richtung;
- END;
- END;
- Flug_Y^[INDEX]:=Richtung;
- END;
- END;
-
- { Nachfolgenden Position einzeichnen }
- PROCEDURE Neu_Position;
- VAR
- INDEX : INTEGER;
- BEGIN
- FOR INDEX:=1 TO Gesamtzahl DO BEGIN
- PutPixel(1+X_Position+X_Richtung-Ort_X^[INDEX],
- 1+Y_Position+Y_Richtung-Ort_Y^[INDEX],Farben^[INDEX]);
- END;
- END;
-
- { Steuerung des äußeren Feldes }
- PROCEDURE Feld;
- BEGIN
- Tasten_Druck;
- END;
-
- BEGIN
- Graph_Init;
- Trichter;
- Start;
- REPEAT
- IF KeyPressed THEN Feld;
-
- { genau eine der beiden folgenden Prozeduren muß aktiv sein }
- { Sie können auch beides mixen - gibt schöne Bilder! }
- Stochastisch;
- {deterministisch;}
-
- Loeschen;
- Neu_Position;
- UNTIL (1=2);
-
- END.
- (* ------------------------------------------------------ *)
- (* Ende von BROWN.PAS *)
-