Atomi mozgások

 

         Az anyag atomjai, molekulái termikus mozgást végeznek. Szilárd testekben egy hely közelében térbeli rezgőmozgás, folyadékokban és gázokban helyváltoztató mozgás figyelhető meg. Folyadékban és gázokban a részecskék mozgására a Brown mozgás létéből következtethetünk, ahol a részecskék az anyagban lebegő makroszkopikus részecskéknek ütközve, azokat rendszertelen, zegzugos mozgásra kényszerítik. Ez a jelenség annál intenzívebb, minél magasabb az anyag hőmérséklete. A helyváltoztató mozgás közben egymással is ütköznek, a mozgás kaotikus lesz.

 

Ez a program az ütközés mellett, néhány, a termikus mozgás következtében létrejövő makroszkopikus jelenséget modellez úgy, hogy az anyag alkotó elemeit látható mértékig növeli, számát viszont kezelhető számosságra csökkenti. A program futási képe animáció nélkül:

 

 

Az animációk a nyomógombokkal indíthatók. Az elindított animációt az újabb animáció leállítja, de csak leállítást elérhetünk a Stop nyomógombbal is.

 

         Két egymástól különböző tömegű részecske ütközésekor az egymásnak okozott lendületváltozások a részecskék tömegével arányos. Az animáció automatikusan akkor is leáll, ha a részecskék elhagyják a képernyőt.

 

 

         Kiterjedés: a kezdetben nagyon kis helyre lokalizált részecske a hő-mozgás következtében egyre nagyobb teret foglal el, végső soron mintegy gázfelhő, egyenletesen kitölti a rendelkezésre álló teret.

 

 

         Keveredés: helyezkedjen el egymáshoz közel két nagyszámú, de különböző részecskékből (kék és piros) álló anyaghalmaz. Ha megengedett a hő-mozgás miatti kapcsolatuk (nincs elválasztó fal köztük), akkor egy bizonyos idő elteltével a részecskék teljesen összekeverednek. A kezdet:

 

 

 

         Rövid idő múlva:

 

 

         A párolgás: az edényben, kezdetben 820 részecske található. A hő-mozgás következtében a folyadék felszínén részecskék távoznak. Mindig az, amelyik elég közel kerül a felülethez, és a mozgás következtében az új helye a folyadékfelszín fölött lenne. A folyamatot lényegesen gyorsíthatjuk a hőmérséklet növelésével, melyet a T+ feliratú nyomógomb segítségével érhetünk el (a T- nyomógomb a hőmérsékletet csökkenti). A kezdet:

 

 

         Melegítéssel gyorsítva a folyamatot:

 

 

         Az ozmózis: az ozmózis jelenségét egy féligáteresztő hártya két oldalán elhelyezkedő folyadék keveredésével mutatjuk be. A féligáteresztő hártya például a kék színű részecskéket nem engedi át, a pirosakat pedig igen. Ennek hatására a baloldali tartályba a jobboldaliból piros részecskék diffundálnak át, és ennek következtében a kezdetben egyenlő nyomásérték megváltozik, a baloldaliban növekszik, a jobboldaliban csökken. A nyomáskülönbséget ozmózisnyomásnak nevezzük. Például, ha egy meggyet, vagy szilvát vízbe helyezünk, akkor a víz molekulái áthatolnak a gyümölcs féligáteresztő héján, és végül az ozmózisnyomás a gyümölcsöket szétrepeszti. Az állapot a folyamat elején:

 

 

         Majd a melegítés hatására, egy bizonyos idő múlva, a következőt láthatjuk:

 

 

         Áramlás: az utolsó animáció egy csőben történő áramlást szemlélteti. A futási kép, amikor a gázfelhő a cső közepén jár:

 

 

         A program listája:

 

unit UAtomok;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, 

  Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

type
  TfmAtomok = class(TForm)
    btUtkozes: TButton;
    btKilepes: TButton;
    tiIdozito: TTimer;
    btStop: TButton;
    btKiterjedes: TButton;
    btKeveredes: TButton;
    btParolgas: TButton;
    btTP: TButton;
    btTM: TButton;
    btOzmozis: TButton;
    btAramlas: TButton;
    lbAtom: TLabel;
    procedure btUtkozesClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btKilepesClick(Sender: TObject);
    procedure tiIdozitoTimer(Sender: TObject);
    procedure btStopClick(Sender: TObject);
    procedure btKiterjedesClick(Sender: TObject);
    procedure btKeveredesClick(Sender: TObject);
    procedure btParolgasClick(Sender: TObject);
    procedure btTPClick(Sender: TObject);
    procedure btTMClick(Sender: TObject);
    procedure btOzmozisClick(Sender: TObject);
    procedure btAramlasClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TAtom= Object
    Fr: Byte;
    Fc: TColor;
    Procedure Init(Ir: Byte; Ic: TColor);
    Procedure SetXY(X, Y: Integer);
    Procedure SetV(Vx, Vy: Integer);
    Procedure Show;
    Procedure Hide;
    Procedure MozogXY(X, Y: Integer);
    Procedure MozogRel(Dx, Dy: Integer);
    Procedure MozogBent(Bx, By, Jx, Jy, Dx, Dy, Tip: Integer);
    Procedure MozogSeb;
    Function GetX: Integer;
    Function GetY: Integer;
    Function GetVx: Integer;
    Function GetVy: Integer;
    Private Fx, Fy, FVx, FVy: Integer;
  End;

Const M= 1000;

var
  fmAtomok: TfmAtomok;
  Xk, Yk, Xm, Ym: Integer;
  Tip: Byte;
  A, B: TAtom;
  Ra, Rb: Integer;
  Sx, Sy: Integer;
  At, Bt: Array[1..M] Of TAtom;
  Bx, By, Jx, Jy: Integer;
  K, L, P, Q, Dx, Dy, T, D: Longint;

implementation

{$R *.dfm}

procedure TfmAtomok.btKilepesClick(Sender: TObject);
begin
  Close;
end;

procedure TfmAtomok.FormCreate(Sender: TObject);
begin
  Xm:= ClientWidth; Xk:= Xm Div 2;
  Ym:= ClientHeight; Yk:= Ym Div 2;
  Tip:= 0;
  Randomize;
end;

Procedure TAtom.Init(Ir: Byte; Ic: TColor);
Begin
  Fr:= Ir; Fc:= Ic; Fx:= -Fr; Fy:= -Fr;
End;

Procedure TAtom.SetXY(X, Y: Integer);
Begin
  Fx:= X; Fy:= Y;
End;

Procedure TAtom.SetV(Vx, Vy: Integer);
Begin
  FVx:= Vx; FVy:= Vy;
End;

Procedure TAtom.Show;
Begin
  With fmAtomok.Canvas Do
  Begin
    Pen.Color:= Fc;
    Brush.Color:= Fc;
    Ellipse(Fx-Fr,Fy-Fr, Fx+Fr,Fy+Fr);
  End;
End;

Procedure TAtom.Hide;
Begin
 With fmAtomok.Canvas Do
  Begin
    Pen.Color:= clBtnFace;
    Brush.Color:= clBtnFace;
    Ellipse(Fx-Fr,Fy-Fr, Fx+Fr,Fy+Fr);
  End;
End;

Procedure TAtom.MozogXY(X, Y: Integer);
Begin
  Hide; SetXY(X, Y); Show;
End;

Procedure TAtom.MozogRel(Dx, Dy: Integer);
Begin
  Hide; SetXY(GetX + Dx, GetY + Dy); Show;
End;

Procedure TAtom.MozogBent(Bx, By, Jx, Jy, Dx, Dy, Tip: Integer);
Begin
  Hide;
  Case Tip Of
    1: Begin   {fent}
         If (GetX+Dx<=Bx+1) Or (GetX+Dx>=Jx-1) Then Dx:= -Dx;
         If (GetY+Dy>=Jy-1) Then Dy:= -Dy;
       End;
    2: Begin   {jobbra}
         If (GetX+Dx<=Bx+1) Then Dx:= -Dx;
         If (GetY+DY<=BY+1) Or (GetY+Dy>=Jy-1) Then Dy:= -Dy;
       End;
    3: Begin   {le}
         If (GetX+Dx<=Bx+1) Or (GetX+Dx>=Jx-1) Then Dx:= -Dx;
         If (GetY+DY<=BY+1) Then Dy:= -Dy;
       End;
    4: Begin   {balra}
         If (GetX+Dx>=Jx-1) Then Dx:= -Dx;
         If (GetY+DY<=BY+1) Or (GetY+Dy>=Jy-1) Then Dy:= -Dy;
       End;
    5: Begin   {fel-le}
         If (GetX+Dx<=Bx+1) Or (GetX+Dx>=Jx-1) Then Dx:= -Dx;
       End;
    6: Begin   {jobbra-balra}
         If (GetY+DY<=BY+1) Or (GetY+Dy>=Jy-1) Then Dy:= -Dy;
       End;
    7: Begin   {fel-jobbra}
         If (GetX+Dx<=Bx+1) Then Dx:= -Dx;
         If (GetY+Dy>=Jy-1) Then Dy:= -Dy;
       End;
    8: Begin   {le-balra}
         If (GetX+Dx>=Jx-1) Then Dx:= -Dx;
         If (GetY+DY<=BY+1) Then Dy:= -Dy;
       End;
    9: Begin   {fel-balra}
         If (GetX+Dx<=Bx+1) Then Dx:= -Dx;
         If (GetY+DY<=BY+1) Then Dy:= -Dy;
       End;
    10: Begin  {le-jobbra}
          If (GetX+Dx>=Jx-1) Then Dx:= -Dx;
          If (GetY+Dy>=Jy-1) Then Dy:= -Dy;
        End;
    11: Begin  {z rt}
         If (GetX+Dx<=Bx+1) Or (GetX+Dx>=Jx-1) Then Dx:= -Dx;
         If (GetY+DY<=BY+1) Or (GetY+Dy>=Jy-1) Then Dy:= -Dy;
       End;
  End;
  MozogRel(Dx, Dy);
  Show;
End;

Procedure TAtom.MozogSeb;
Begin
  Hide; SetXY(GetX + FVx, GetY + FVy); Show;
End;

Function TAtom.GetX: Integer;
Begin
  GetX:= Fx;
End;

Function TAtom.GetY: Integer;
Begin
  GetY:= Fy;
End;

Function TAtom.GetVx: Integer;
Begin
  GetVx:= FVx;
End;

Function TAtom.GetVy: Integer;
Begin
  GetVy:= FVy;
End;

procedure TfmAtomok.btUtkozesClick(Sender: TObject);
begin
  btStopClick(Sender);
  Ra:= 25; Rb:= 10;
  With A Do Begin Init(Ra, clBlue); SetXY( 0,0); SetV( 3,2); Show End;
  With B Do Begin Init(Rb, ClRed); SetXY(Xk,0); SetV(-2,2); Show End;
  Tip:= 1;
end;

procedure TfmAtomok.btKiterjedesClick(Sender: TObject);
Var I: Word;
begin
  btStopClick(Sender);
  For I:= 1 To M Do With At[I] Do
  Begin Init(1,clRed); SetXY(Xk,Yk); Show End;
  Tip:= 2;
end;

procedure TfmAtomok.btKeveredesClick(Sender: TObject);
Var I: Word;
begin
  btStopClick(Sender);
  For I:= 1 To M Do With At[I] Do
  Begin Init(1,clBlue); SetXY(Xk-20,Yk); Show End;
  For I:= 1 To M Do With Bt[I] Do
  Begin Init(1,clRed); SetXY(Xk+20,Yk); Show End;
  Tip:= 3;
end;

procedure TfmAtomok.btParolgasClick(Sender: TObject);
Var I, J: Word;
begin
  btStopClick(Sender);
  Bx:= Round(0.3*Xm); By:= Yk;
  Jx:= Round(0.7*Xm); Jy:= Round(0.8*Ym);
  With Canvas Do
  Begin
    With Pen Do
    Begin
      Color:= clWhite;
      Width:= 3;
    End;
    MoveTo(Bx, Round(0.4*Ym)); LineTo(Bx, Jy);
    LineTo(Jx, Jy); LineTo(Jx, Round(0.4*Ym));
    Pen.Color:= clBlue;
    MoveTo(Bx+1, By); LineTo(Jx-1, By);
  End;
  K:= Jx - Bx - 2; L:= Jy - By - 2;
  P:= Round(Sqrt(K*M/L))-3; Q:= Round(Sqrt(L*M/K))-3;
  Dx:= Round(K/P); Dy:= Round(L/Q);
  For J:= 1 To Q Do For I:= 1 To P Do With At[(J-1)*P+I] Do
  Begin Init(1,clBlue); SetXY(Bx+(I-1)*Dx+4, By+(J-1)*Dy+4); Show End;
  T:= 3;
  Tip:= 4;
end;

procedure TfmAtomok.btOzmozisClick(Sender: TObject);
Var I, J: Word;
begin
  btStopClick(Sender);
  Bx:= Round(0.2*Xm); By:= Round(0.25*Ym);
  Jx:= Round(0.8*Xm); Jy:= Round(0.75*Ym);
  With Canvas Do
  Begin
    With Pen Do
    Begin
      Color:= clWhite;
      Width:= 3;
    End;
    Brush.Color:= clBtnFace;
    Rectangle(Bx,By, Jx,Jy);
    MoveTo(Xk, By+1); LineTo(Xk, Jy-1);
  End;
  K:= (Jx - Bx) Div 2 - 2; L:= Jy - By - 2;
  P:= Round(Sqrt(K*M/L))-2; Q:= Round(Sqrt(L*M/K))-2;
  Dx:= Round(K/P); Dy:= Round(L/Q);
  For J:= 1 To Q Do For I:= 1 To P Do With At[(J-1)*P+I] Do
  Begin Init(1,clBlue); SetXY(Bx+(I-1)*Dx+6, By+(J-1)*Dy+6); Show End;
  For J:= 1 To Q Do For I:= 1 To P Do With Bt[(J-1)*P+I] Do
  Begin Init(1,clRed); SetXY(Xk+(I-1)*Dx+6, By+(J-1)*Dy+6); Show End;
  T:= 3;
  Tip:= 5;
end;

procedure TfmAtomok.btAramlasClick(Sender: TObject);
Var I: Word;
begin
  btStopClick(Sender);
  D:= 20;
  With Canvas Do
  Begin
    With Pen Do
    Begin
      Color:= clBlack;
      Width:= 1;
    End;
    MoveTo(0,Yk-D); LineTo(Xm,Yk-D); MoveTo(0,Yk+D); LineTo(Xm,Yk+D);
  End;
  For I:= 1 To M Do With At[I] Do
  Begin Init(1,clBlue); SetXY(0,Yk); Show End;
  T:= 3;
  Tip:= 6;
end;

procedure TfmAtomok.btTPClick(Sender: TObject);
begin
  Inc(T,2);
end;

procedure TfmAtomok.btTMClick(Sender: TObject);
begin
  If T>4 Then Dec(T,2);
end;

procedure TfmAtomok.tiIdozitoTimer(Sender: TObject);
Var I, S, Sa, Sb: Word;
begin
  Case Tip Of
    1: Begin
         If B.GetX-A.GetX<= Ra+Rb Then
         Begin
           Sx:= Round(2*(Ra*Ra*A.GetVx+Rb*Rb*B.GetVx)/(Ra*Ra+Rb*Rb));
           Sy:= Round(2*(Ra*Ra*A.GetVy+Rb*Rb*B.GetVy)/(Ra*Ra+Rb*Rb));
           A.SetV(Sx-A.GetVx, Sy-A.GetVy);
           B.SetV(Sx-B.GetVx, Sy-B.GetVy)
         End;
         A.MozogSeb; B.MozogSeb;
         If (A.GetX>2*Xk) And (A.GetY>2*Yk) And
            (B.GetX>2*Xk) And (B.GetY>2*Yk) Then btStopClick(Sender);
       End;
    2: For I:= 1 To M Do At[I].MozogRel(Random(5)-2, Random(5)-2);
    3: For I:= 1 To M Do
         Begin
           At[I].MozogRel(Random(5)-2, Random(5)-2);
           Bt[I].MozogRel(Random(5)-2, Random(5)-2);
         End;
    4: Begin
         S:= 0;
         For I:= 1 To Q*P Do With AT[I] Do
         Begin
           If GetY>By Then
           Begin
             Inc(S);
             MozogBent(Bx+2, By+2, Jx-2, Jy-2,
                       Random(T)-(T Div 2),Random(T)-(T Div 2),1);
           End Else Hide;
           With Canvas Do
           Begin
             Pen.Color:= clBlue;
             MoveTo(Bx+1, By); LineTo(Jx-1, By);
           End;
         End;
         With Canvas Do
         Begin
           Pen.Color:= clBlue;
           Brush.Color:= clBtnFace;
           Font.Size:= 24;
           TextOut(Xk-20,50,IntToStr(S)+'/'+IntToStr(T)+'     ');
         End;
       End;
    5: Begin
         Sa:= 0; Sb:= 0;
         For I:= 1 To Q*P Do With AT[I] Do
         Begin
           Inc(Sa);
           MozogBent(Bx+2, By+2, Xk-2, Jy-2,
                     Random(T)-(T Div 2), Random(T)-(T Div 2),11);
         End;
         For I:= 1 To Q*P Do With BT[I] Do
         Begin
           If GetX<Xk Then Inc(Sa) Else Inc(Sb);
           MozogBent(Bx+2, By+2, Jx-2, Jy-2,
                     Random(T)-(T Div 2), Random(T)-(T Div 2),11);
         End;
         With Canvas Do
         Begin
           Pen.Color:= clBlue;
           MoveTo(Xk,By+1); LineTo(Xk,Jy-1);
           Font.Size:= 24;
           Brush.Color:= clBtnFace;
           TextOut(Xk Div 2-20,50,IntToStr(Sa)+'    ');
           TextOut(Xk, 50, IntToStr(T)+'    ');
           TextOut(Xk+Xk Div 2-20,50,IntToStr(Sb)+'    ');
         End;
       End;
    6: For I:= 1 To M Do
       At[I].MozogBent(0,Yk-D, Xm,Yk+D,
                       Random(T)-(T Div 2)+1, Random(T)-(T Div 2),6);
  End;
end;

procedure TfmAtomok.btStopClick(Sender: TObject);
Var I: Word;
begin
  A.Hide; B.Hide;
  For I:= 1 To M Do Begin At[I].Hide; Bt[I].Hide End;
  Canvas.Rectangle(0,0,Xm,Ym);
  Tip:= 0;
  lbAtom.Repaint;
end;

end.