unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Math, ComCtrls;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
PaintBox1: TPaintBox;
EditL: TEdit;
EditH: TEdit;
EditNum: TEdit;
EditRad: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
UpDownNum: TUpDown;
ButtonGo: TButton;
ButtonStop: TButton;
ButtonColor: TButton;
ButtonFon: TButton;
ColorDialog1: TColorDialog;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure ButtonFonClick(Sender: TObject);
procedure ButtonColorClick(Sender: TObject);
procedure ButtonGoClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure ButtonStopClick(Sender: TObject);
procedure UpDownNumClick(Sender: TObject; Button: TUDBtnType);
procedure EditNumKeyPress(Sender: TObject; var Key: Char);
procedure ButtonGoKeyPress(Sender: TObject; var Key: Char);
procedure GroupBox1Click(Sender: TObject);
private
{ Private declarations }
procedure Painting;
public
{ Public declarations }
end;
type
TMolekula = class
Fx, Fy, FVx, FVy, FR : Integer;
public
constructor Create(x, y, Vx, Vy : integer);
procedure Wall(i : integer; width, height : integer);
procedure Strike(i : integer);
end;
type
TMolekulaList = Class(TList)
public
procedure Add(Mol : TMolekula);
procedure Clear;
procedure Delete(n : integer);
end;
const MaxSpeed=10;
var
Form1: TForm1;
Molcolor: TColor;
FonColor: TColor;
Mollist: TMolekulaList;
pbWidth, pbHeight: integer;
Rad: integer;
implementation
{$R *.dfm}
Constructor TMolekula.Create(x, y, Vx, Vy : integer);
begin
Fx := x;
Fy := y;
FVx := Vx;
FVy := Vy;
FR := Rad;
end;
function CreateMol: TMolekula;
var x, y, vx, vy : integer;
begin
x := RandomRange(Rad, pbWidth - Rad);
y := RandomRange(Rad, pbHeight - Rad);
Vx:= RandomRange(1, MaxSpeed);
Vy:= RandomRange(1, MaxSpeed);
if RandomRange(1, 100) > 50 then Vx := -Vx;
if RandomRange(1, 100) > 50 then Vy := -Vy;
Result := TMolekula.Create(x, y, Vx, Vy);
end;
Function DistanceBetween(Mol1, Mol2 : TMolekula) : real;
begin
Result:= sqrt(sqr(Mol1.Fx - Mol2.Fx) + sqr(Mol1.Fy - Mol2.Fy));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MolColor := clBlack;
FonColor := clSilver;
MolList := TMolekulaList.Create;
Randomize;
end;
procedure TForm1.GroupBox1Click(Sender: TObject);
begin
end;
procedure TForm1.ButtonFonClick(Sender: TObject);
begin
if ColorDialog1.Execute then
FonColor := ColorDialog1.Color;
end;
procedure TForm1.ButtonColorClick(Sender: TObject);
begin
if ColorDialog1.Execute then
MolColor := ColorDialog1.Color;
end;
procedure TForm1.ButtonGoClick(Sender: TObject);
var i, n : integer;
Mol : TMolekula;
begin
PaintBox1.Width := pbWidth;
PaintBox1.Height := pbHeight;
pbWidth := StrToInt(editL.Text);
pbHeight:= StrToInt(editH.Text);
n := strToInt(editNum.Text);
Rad := strToInt(editRad.Text);
if (Rad=0) or (n=0) then
begin
ShowMessage ('Количество молекул и/или радиус молекул не могут быть равны 0');
exit;
end;
if (pbWidth*pbHeight)<Trunc (n*pi*Rad*Rad) then
begin
ShowMessage ('Сосуд маленький для таких молекул');
exit;
end;
MolList.Clear;
MolList.Clear;
for i := 1 to n do
begin
Mol := CreateMol;
MolList.Add(Mol);
end;
timer1.Enabled:=true;
ButtonStop.Caption:= 'Стоп';
end;
procedure TForm1.ButtonGoKeyPress(Sender: TObject; var Key: Char);
begin
if key =#13 then ButtonGo.Click;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var x, y : integer;
i : integer;
Mol : TMolekula;
begin
for i:=0 To MolList.Count-1 do
begin
Mol := TMolekula(MolList.Items[i]);
Mol.Fx := Mol.Fx + Mol.FVx;
Mol.Fy := Mol.Fy + Mol.FVy;
Mol.Wall(i, pbwidth, pbheight);
Mol.Strike(i);
Painting;
end;
end;
procedure TForm1.ButtonStopClick(Sender: TObject);
begin
Timer1.Enabled:= not Timer1.Enabled;
if Timer1.Enabled then
ButtonStop.Caption:= 'Стоп'
else
ButtonStop.Caption:= 'Продолжить'
end;
procedure TForm1.EditNumKeyPress(Sender: TObject; var Key: Char);
begin
if key =#13 then
begin
ButtonGo.Click;
end;
end;
procedure TForm1.UpDownNumClick(Sender: TObject; Button: TUDBtnType);
var Mol: TMolekula;
begin
if ButtonStop.Caption = 'Стоп' then
if Button = btNext then
begin
Mol := CreateMol;
MolList.Add(Mol);
end
else
if MolList.Count > 1 then
MolList.Delete(0);
end;
procedure TMolekula.Wall(i:integer; width, height:integer);
var
Mol : TMolekula;
begin
Mol := TMolekula(MolList.Items[i]);
if Mol.Fx + Rad >= width then
begin
Mol.FVx := -Mol.FVx;
Mol.Fx := width - Rad;
end
else
if Mol.Fy + Rad >= height then
begin
Mol.FVy := -Mol.FVy;
Mol.Fy := height - Rad;
end
else
if Rad >= width then
begin
Mol.FVx := -Mol.FVx;
Mol.Fx := width;
end
else
if Rad >= height then
begin
Mol.FVy := -Mol.FVy;
Mol.Fy := height;
end;
if Mol.Fx - Rad <= 0 then
begin
Mol.FVx := -Mol.FVx;
Mol.Fx := Rad;
end
else
if Mol.Fy - Rad <= 0 then
begin
Mol.FVy := -Mol.FVy;
Mol.Fy := Rad;
end;
end;
procedure TMolekula.Strike(i : integer);
var j : byte;
Mol1, Mol2 : TMolekula;
temp : integer;
begin
Mol1:=TMolekula(MolList.Items[i]);
for j := 0 to MolList.Count - 1 do
begin
if j <> i then
begin
Mol2 := TMolekula(MolList.Items[j]);
if DistanceBetween(Mol1, Mol2) <= 2 * Rad then
begin
temp := Mol1.FVx;
Mol1.FVx := Mol2.FVx;
Mol2.FVx := temp;
temp := Mol1.FVy;
Mol1.FVy := Mol2.FVy;
Mol2.FVy := temp;
break;
end;
end;
end;
end;
procedure TMolekulaList.Add(Mol: TMolekula);
begin
inherited Add(Mol);
end;
procedure TMolekulaList.Clear;
var i: integer;
begin
for i := 0 to Count - 1 do TMolekula(Items[i]).Free;
Inherited Clear;
end;
procedure TMolekulaList.Delete(n: integer);
begin
if (n >=0) and (n <= Count - 1) then
begin
TMolekula(Items[n]).Free;
Inherited Delete(n);
end;
end;
procedure TForm1.Painting;
var
i : Integer;
Mol : TMolekula;
begin
paintBox1.Canvas.Brush.Color := FonColor;
PaintBox1.Canvas.Rectangle(0, 0, pbWidth, pbHeight);
PaintBox1.Canvas.Brush.Color := MolColor;
for i := 0 to MolList.Count - 1 do
begin
Mol := TMolekula(MolList.Items[i]);
PaintBox1.Canvas.Ellipse(Mol.Fx - Rad, Mol.Fy - Rad,
Mol.Fx + Rad, Mol.Fy + Rad);
end;
end;
end.
Avg: record
X,Y: single
end;
Mol := CreateMol;
Avg.X := Avg.X + Mol.FVx;
Avg.Y := Avg.Y + Mol.FVy;
end;
Avg.X := Abs(Avg.X / n);
Avg.Y := Abs(Avg.Y / n);
Label5.Caption := Format('Средняя скорость по X=%f Y=%f', [Avg.X,Avg.Y]);
Avg.X := Avg.X + Mol.FVx;
Avg.Y := Avg.Y + Mol.FVy;
Avg.X := Avg.X + ABS(Mol.FVx);
Avg.Y := Avg.Y + ABS(Mol.FVy);
Vx:= RandomRange(1, MaxSpeed);
Vy:= RandomRange(1, MaxSpeed);
if RandomRange(1, 100) > 50 then Vx := -Vx;
if RandomRange(1, 100) > 50 then Vy := -Vy;
Vx:= RandomRange(-MaxSpeed, MaxSpeed);
Vy:= RandomRange(-MaxSpeed, MaxSpeed);
procedure TForm1.Timer1Timer(Sender: TObject);
var
i,x, y : integer;
Mol : TMolekula;
begin
x:=0;
y:=0;
for i:=0 To MolList.Count-1 do
begin
Mol := TMolekula(MolList.Items[i]);
Mol.FVx:=Mol.FVx+RandomRange(-1, 1);
Mol.FVy:=Mol.FVx+RandomRange(-1, 1);
x:=x+abs(Mol.FVx);
y:=y+abs(Mol.FVy);
Mol.Fx := Mol.Fx + Mol.FVx;
Mol.Fy := Mol.Fy + Mol.FVy;
Mol.Wall(i, pbwidth, pbheight);
Mol.Strike(i);
Painting;
end;
Label5.Caption := Format('Средняя скорость по X=%f Y=%f', [X/MoList.Count,Y/MolList.Count]);
end;
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.