Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Практический курс математического и компьютерного моделирования. Учебно-практическое пособие
.pdf
II. Программная реализация математической модели
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end. // конец файла coordinateUnit.pas.
II.6.2. Класс для модели,
не учитывающей сопротивление воздуха
// файл y1_Unit.pas
unit y1_Unit;
interface
uses coordinateUnit;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// вертикальная координата мат. точки, падающей в пустоте
// под действием силы тяжести c нач. скоростью v0, нап // равленной вертикально вверх (вниз) y'' = -g, y(t0) = y0, y'(t0) = v0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type Ty1 = class( Tcoordinate )
protected
C1 : double; // константы
C2 : double; // интегрирования;
function position( t: double ): double; override;
function velocity( t: double ): double; override;
public
constructor birth( tt0, yy0, vv0, kk: double; NN: LongWord );
destructor Kill; override;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// координата точки
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Ty1.position( t: double ): double;
begin
result := -0.5*g*t*t + C1*t + C2;
end;
61

Математическое и компьютерное моделирование
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// скорость точки
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Ty1.velocity( t: double ): double;
begin
result := -g*t + C1;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
constructor Ty1.birth( tt0, yy0, vv0, kk: double; NN: LongWord );
begin
inherited birth( tt0, yy0, vv0, kk, NN );
C1 := g*tt0 + vv0;
C2 := yy0 + 0.5*g*tt0*tt0 - C1*tt0;
calc_t_impact;
calc_v_impact;
calc_max_value;
calc_values;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
destructor Ty1.Kill;
begin
inherited Kill;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end. // конец файла y1_Unit.pas.
II.6.3. Класс для модели,
учитывающей сопротивление воздуха
// файл y2_Unit.pas
unit y2_Unit;
interface
uses coordinateUnit;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// вертикальная координата мат. точки, падающей под дейст-
62

II. Программная реализация математической модели
// вием силы тяжести c начальной скоростью v0, направленной
// вертикально вверх (вниз), с учетом сопротивления воздуха
// y'' = -g - uy', y(t0) = y0, y'(t0) = v0;
// ограничение: uv0 > -g, u > 0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type Ty2 = class( Tcoordinate )
protected
C1 : double; // константы
C2 : double; // интегрирования;
u : double; // коэфф. сопротивления среды;
top_v_list : value_list; // указатель на "верх" списка;
procedure calc_v; // определение скоростей точки;
function position( t: double ): double; override;
function velocity( t: double ): double; override;
public
function get_v_list : value_list;
constructor birth( tt0, yy0, vv0, kk, uu: double; NN: LongWord );
destructor Kill; override;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// координата точки
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Ty2.position( t: double ): double;
begin
result := -C1*exp( -u*t )/u - g/u*t + C2;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// скорость точки
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Ty2.velocity( t: double ): double;
begin
result := C1*exp( -u*t ) - g/u;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// расчет значений
скоростей точки на отр. [t0; t_impact] c шагом
63

Математическое и компьютерное моделирование
4
// delta_t и занесение их в список, на вершину которого указывает
// top_v_list
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure Ty2.calc_v;
var t, delta_t : double;
ptr : value_list;
begin
if ( t0 >= t_impact ) then exit;
t := t_impact;
delta_t := ( t_impact - t0 )/N;
while ( t >= t0 ) do // список заполняется значени-
begin // ями скоростей по убыванию
new( ptr ); // аргумента,поэтому, в "вер-
ptr.value := velocity( t ); // шине"стека окажется самое
ptr.link := top_v_list; // первое значение скорости;
top_v_list := ptr;
t := t - delta_t;
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Ty2.get_v_list : value_list;
begin
result := top_v_list;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
constructor Ty2.birth( tt0, yy0, vv0, kk, uu: double; NN: LongWord );
begin
inherited birth( tt0, yy0, vv0, kk, NN );
u := uu;
C1 := ( vv0 + g/uu )*exp( uu*tt0 );
C2 := yy0 + C1/uu*exp( -uu*tt0 ) + g/uu*tt0;
calc_t_impact;
calc_v_impact;
calc_max_value;
calc_values;
new( top_v_list );
6

II. Программная реализация математической модели
top_v_list.link := NIL;
calc_v;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
destructor Ty2.Kill;
var ptr : value_list;
begin
while ( top_v_list.link <> NIL ) do
begin // освобождение выделенной
ptr := top_v_list; // для хранения списка
top_v_list := top_v_list^.link; // величин скоростей
dispose( ptr ); // памяти;
end;
dispose( top_v_list );
inherited Kill;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
end. // конец файла y2_Unit.pas.
II.6.4. Модуль, поддерживающий графику
// файл ballFormUnit.pas, поддержка анимации
unit ballFormUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ExtCtrls, ComCtrls;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type TForm_ball = class( Tform )
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure FormCanResize( Sender : TObject; var NewWidth,
NewHeight : Integer;
var Resize: Boolean );
private
cvet_fon : TColor; // цвет фона;
65

Математическое и компьютерное моделирование
6
JM, J0, I0, IM : integer; // параметры окна для графики;
WForm, HForm : integer; // клиентская часть формы;
function J( y: Double ) : integer; // масштабирование y;
procedure Delay( s: Double ); // задержка;
public
procedure Frame( yy: Double; ott: Double; // прорисовка кадра
CLEAR_FLAG: Boolean = TRUE ); //анимации;
procedure ClearWind; // очиска окна;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var Form_ball : TForm_ball;
maxH : Double; // макс. высота подъема шара;
const radius = 15; // радиус шара;
implementation
{$R *.dfm}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// масштабирование и преобразование ординаты y;
// "реальная" координата y переводится в экранную J(y)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function TForm_ball.J( y: Double ): integer;
begin
if ( maxH > 0.0 )
then result := JM - J0 - trunc( y*(JM - J0)/maxH ) + radius
else result := 0;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// задержка на s. ЗАМЕЧАНИЕ: точность измерения интервала
// времени не
превосходит 0.055 секунды (1 "тик" CPU)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_ball.Delay( s : Double );
var tick0 : LongWord;
begin
tick0 := getTickCount;
repeat
Application.ProcessMessages;
until ( ( ( getTickCount - tick0 )/0.055 ) >= 10*s );
6

II. Программная реализация математической модели
7
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// кадр анимации с задержкой ott секунд;
// если сброшен CLEAR_FLAG, стирания не происходит
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_ball.Frame( yy: Double; ott: Double;
CLEAR_FLAG: Boolean = TRUE );
var Jy, Imid : integer;
begin
Jy := J( yy );
Imid := round( I0 + IM/2 - radius );
Canvas.Pen.Color := clBlack;
Canvas.Ellipse( Imid, Jy - radius, Imid + 2*radius, Jy + radius );
Delay( ott );
if ( CLEAR_FLAG ) then
begin
Canvas.Pen.Color := cvet_fon;
Canvas.Ellipse( Imid, Jy - radius, Imid + 2*radius, Jy + radius );
end;
Canvas.Pen.Color := clBlack;
StatusBar1.SimpleText := ' y = ' + FloatToStrF( yy, ffGeneral, 6, 3 );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// очистка окна вывода
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_ball.ClearWind;
var Wnd : TRect;
begin
Wnd := Rect( 0, 0, WForm, HForm );
Canvas.Brush.Color := cvet_fon;
Canvas.FillRect( Wnd );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_ball.FormCreate( Sender: TObject );
begin
cvet_fon := Form_ball.Color;
Canvas.Brush.Style := bsClear;
6

Математическое и компьютерное моделирование
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_ball.FormCanResize( Sender : TObject;
var NewWidth,
NewHeight : Integer;
var Resize : Boolean );
begin
WForm := Form_ball.ClientWidth;
HForm := Form_ball.ClientHeight - StatusBar1.Height;
J0 := 0;
JM := HForm - 2*radius;
I0 := 0;
IM := WForm;
ClearWind;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
end. // конец файла ballFormUnit.pas.
II.6.5. Головной модуль
// головной файл mainUnit.pas
unit mainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,
coordinateUnit, y1_Unit, y2_Unit, ballFormUnit, TeEngine,
Series, TeeProcs, Chart, Menus;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type TForm_main = class( TForm )
StatusBar1 : TStatusBar;
Panel1 : TPanel;
STARTbutton : TButton;
Edit_y0 : TEdit;
Edit_v0 : TEdit;
68

II. Программная реализация математической модели
Edit_N :TEdit;
Edit_tau : TEdit;
Label1 : TLabel;
Label2 : TLabel;
Label3 : TLabel;
Label4 : TLabel;
RadioGroup1: TRadioGroup;
Edit_k : TEdit;
Label5 : TLabel;
Edit_imp : TEdit;
Label6 : TLabel;
INITButton : TButton;
Edit_u : TEdit;
Label7 : TLabel;
Chart1 : TChart;
Series1 : TLineSeries;
MainMenu1 : TMainMenu;
File1 : TMenuItem;
Exite1 : TMenuItem;
Help : TMenuItem;
About1 : TMenuItem;
procedure STARTbuttonClick( Sender: TObject );
procedure RadioGroup1Click( Sender: TObject );
procedure INITButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure About1Click(Sender: TObject);
procedure Exite1Click(Sender: TObject);
procedure ShowHint(Sender: TObject);
private
y1 : Ty1;
y2 : Ty2;
q,q_v : value_list;
y0, v0, tau : double;
k, u : double;
N, impacts : LongWord;
procedure Engine_Y1;
69

Математическое и компьютерное моделирование
procedure Engine_Y2;
public
{ Public declarations }
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var Form_main: TForm_main;
implementation
{$R *.dfm}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// движок модели, не учитывающей сопротивление среды
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.Engine_Y1;
var t0, dt, t : double;
impact_count : LongWord;
begin
t0 := 0.0;
impact_count := 1; // счетчик ударов;
dt := ( y1.get_t_impact - t0 )/N;
Form_ball.Frame( q.value, dt*tau );
q := q^.link;
t := dt;
while ( impact_count <= impacts ) do
begin
Form_ball.Frame( 0.0, 0.0 );
while ( q.link <> NIL ) do
begin
Form_ball.Frame( q.value, dt*tau );
Series1.AddXY( t, q.value );
q := q^.link;
t := t + dt;
end;
Form_ball.Frame( 0.0, dt*tau, FALSE ); // момент удара:
t0 := y1.get_t_impact; // новые начальные значения
v0 := y1.get_v_impact; // времени и скорости;
y1.Kill;
StatusBar1.SimpleText := IntToStr( impact_count) +'-й удар:'
70
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
