Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Практический курс математического и компьютерного моделирования. Учебно-практическое пособие
.pdf
II. Программная реализация математической модели
+ ' время ' +
FloatToStrF( t0, ffGeneral, 5,2 )
+ ', скорость '+
FloatToStrF( v0, ffGeneral, 5,2 );
y1 := Ty1.birth( t0, 0, -k*v0, k, trunc( N*k ) + 1 );
dt := ( y1.get_t_impact - t0 )/N;
q := y1.get_top_list;
inc( impact_count );
end; // while ( impact_count <= impacts )...
y1.Kill;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// движок модели, учитывающей сопротивление среды
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.Engine_Y2;
var t0, dt, t : double;
impact_count : LongWord;
begin
t0 := 0.0;
impact_count := 1; // счетчик ударов;
dt := ( y2.get_t_impact - t0 )/N;
Form_ball.Frame( q.value, dt*tau );
q := q^.link;
q_v := q_v^.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, u*q_v.value );
q := q^.link;
q_v := q_v^.link;
t := t + dt;
end;
71

Математическое и компьютерное моделирование
Form_ball.Frame( 0.0, dt*tau, FALSE ); // момент удара:
t0 := y2.get_t_impact; // новые начальные значения
v0 := y2.get_v_impact; // времени и скорости;
y2.Kill;
StatusBar1.SimpleText := IntToStr( impact_count) +'-й удар:'
+ ' время ' +
FloatToStrF( t0, ffGeneral, 5,2 )
+ ', скорость '+
FloatToStrF( v0, ffGeneral, 5,2 );
y2 := Ty2.birth( t0, 0, -k*v0, k, u, trunc( N*k ) + 1 );
dt := ( y2.get_t_impact - t0 )/N;
q := y2.get_top_list;
q_v := y2.get_v_list;
inc( impact_count );
end; // while ( impact_count <= impacts )...
y2.Kill;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.STARTbuttonClick( Sender: TObject );
begin
STARTbutton.Enabled := FALSE;
StatusBar1.SimpleText := '';
Series1.Clear;
if ( RadioGroup1.ItemIndex = 0 ) then Engine_Y1;
if ( RadioGroup1.ItemIndex = 1 ) then Engine_Y2;
RadioGroup1.Enabled := TRUE;
INITbutton.Enabled := TRUE;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.RadioGroup1Click( Sender: TObject );
begin
if ( RadioGroup1.ItemIndex = 0 )
then Edit_u.Enabled := FALSE;
if ( RadioGroup1.ItemIndex = 1 )
then Edit_u.Enabled := TRUE;
end;
72

II. Программная реализация математической модели
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// инициализация входных параметров моделей и их движков,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.INITButtonClick( Sender: TObject );
begin
INITbutton.Enabled := FALSE;
RadioGroup1.Enabled := FALSE;
try begin // обработка ошибок ввода данных:
y0 := StrToFloat( Edit_y0.Text );
v0 := StrToFloat( Edit_v0.Text );
N := StrToInt ( Edit_N.Text );
k := StrToFloat( Edit_k.Text );
u := StrToFloat( Edit_u.Text );
tau := StrToFloat( Edit_tau.Text );
impacts := StrToInt ( Edit_imp.Text );
end
except on EConvertError
do begin
ShowMessage( 'Неверный ввод данных' + #13#10 +
‘проверьте десятичную ./,' );
INITbutton.Enabled := TRUE;
exit;
end;
end; // конец обработки ошибок ввода данных;
// обработка ввода ошибочных параметров модели:
if ( (y0 < 0) OR ( (k < 0) OR (k > 1) ) OR (u <= 0) )
then
begin
ShowMessage( 'Должно быть' + #13#10
+ 'y0 >= 0; 0 <= k < 1; u > 0' );
INITbutton.Enabled := TRUE;
exit;
end;
if ( ( y0 = 0 ) AND ( v0 = 0 ) ) then
begin
ShowMessage( 'Не должно быть одновременно' + #13#10 +
73

Математическое и компьютерное моделирование
4
'y0 = 0 и v0 = 0' );
INITbutton.Enabled := TRUE;
exit;
end; // конец обработки ввода ошибочных параметров;
if ( RadioGroup1.ItemIndex = 0 ) then // выбор модели 1;
begin
y1 := Ty1.birth( 0.0, y0, v0, k, N );
q := y1.get_top_list;
maxH := y1.get_Max_value;
Chart1.Title.Text.Text:='Зависимость коорд. от времени';
end;
if ( RadioGroup1.ItemIndex = 1 ) then // выбор модели 2;
begin
if ( u*v0 <= -g ) then
begin
ShowMessage( 'Должно быть' + #13#10 + ' u*v0 > -g' );
INITbutton.Enabled := TRUE;
exit;
end;
y2 := Ty2.birth( 0.0, y0, v0, k, u, N );
q := y2.get_top_list;
maxH := y2.get_Max_value;
q_v := y2.get_v_list;
Chart1.Title.Text.Text := ' Зависимость сопротивления'
+ ' среды от времени';
end;
if ( not Assigned ( Form_ball ) )
then Form_ball := TForm_ball.Create( self );
Form_ball.Show;
Form_ball.ClearWind;
Form_ball.Frame( q.value, 0, FALSE );
STARTbutton.Enabled := TRUE;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.FormCreate( Sender: TObject );
begin
STARTbutton.Enabled := FALSE;
7

II. Программная реализация математической модели
5
Edit_u.Enabled := FALSE;
Application.OnHint := ShowHint;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.About1Click(Sender: TObject);
begin
ShowMessage( 'В. Зенкин, КГУ, 2005 г.' + #13#10 + 'модель пры-
гающего мяча' + #13#10 + 'учебный пример' );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.Exite1Click(Sender: TObject);
begin
Close;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure TForm_main.ShowHint(Sender: TObject);
begin
StatusBar1.SimpleText := Application.Hint;
end;
end. // конец головного файла mainUnit.pas.
II.7. Пример 2. Реалистичное освещение
Рассмотрим программную реализацию модели, построенной в
I.4, не останавливаясь подробно на вопросах проектирования ие-
рархии классов, так как ее вид в данном случае вполне очевиден.
Для того чтобы иметь возможность работать с лучами и задавать координаты точек в пространстве (рис. II. 5 — координатная
система), нужны векторы — соответствующие процедуры и
функции сосредоточим в
классе31 Tvector (см. листинги) и в моду-
ле vectorUnit. Для работы с цветами нам понадобятся соответст-
31
Нужно заметить, что на языках, допускающих перегрузку операций,
например на C++, данный класс выглядел бы более элегантно.
7

Математическое и компьютерное моделирование
6
вующие процедуры и функции32 — модуль colorUnit. Объект
луч, который нужен для работы с источником света, по существу
является вектором, имеющим цвет, поэтому выведем соответствующий класс
Tray из класса Tvector (см. листинги).
Рис. II. 5
Несмотря на то что в нашей модели только один тип тел —
сфера, с учетом возможных дальнейших модификации программы, когда к сферам на сцену могут добавиться и другие
виды объектов, сосредоточим общие для них методы в базовом
классе
женного луча, вычисления коэффициентов диффузии и отражения в заданной точке, для которых нужно знать нормаль к данной точке. Поскольку нормаль можно определить только для
конкретного тела, то метод
абстрактным — с тем, чтобы в дальнейшем иметь возможность
его переопределения в производных классах.
класса должен иметь возможность рассчитывать вектор нормали
32
цвета в виде тройки компонент: красной (Red), зелёной (Green) и синей
(Blue). Такую модель называют RGB. В данной программе используется
24-битовый цвет, по 8 бит на каждую цветовую компоненту; таким образом, всего программа может отобразить 2
7
Tfigure. Этот класс содержит методы для расчета отра-
set_normal объявлен виртуальным и
Из класса
Используется традиционное для компьютерной графики представление
Tfigure выведем класс Tsphere (сфера). Объект этого
24
различных цветов.

II. Программная реализация математической модели
7
к любой точке своей поверхности, определять факт пересечения
трассирующего луча с поверхностью и, кроме того, определять
расстояние до камеры. Для этого в классе
Tsphere заданы методы
set_normal и intersection, последний из которых возвращает множи-
t, на который нужно умножить направляющий вектор трас-
тель
сирующего луча, чтобы этот луч попал на сферу. Если луч не
попадает на сферу, то метод возвращает -1,0. В модуле traceUnit
содержится процедура инициализации сцены
init_scene (исполь-
зуется левая координатная система — см. рис., картинная плоскость фиксирована и совпадает с плоскостью XY), задающая положение камеры, источника света, количество и параметры сфер
и т.д., и трассировщик —
рекурсивная функция trace, которая
собственно и выполняет всю основную работу по трассировке
лучей. Алгоритм работы трассировщика вполне понятен из комментариев к исходному коду и описания, приведенного в I.4.
Головной модуль mainUnit содержит процедуру отрисовки
изображения, средства для поддержки управления программой
и для сохранения трассированного изображения в файле (на
рисунке II. 6 — окно программы на этапе выполнения).
Рис. II.6
Прекрасным примером реализации идей рейтрессинга является программа POV-Ray (Persistence of Vision Raytracer).
Эта программа свободно распостраняется, причем с исходны-
7

Математическое и компьютерное моделирование
ми кодами (на языке C++), снабжена отличной справочной
документацией. На сайте разработчиков [33] можно найти
множество материалов по рейтрессингу и соответствующему
программному обеспечению.
II.8. Листинги примера 2
II.8.1. Базовый класс tvector (вектор)
и векторные операции
// файл vectorUnit.pas
unit vectorUnit;
interface
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type Tpoint3D = record
x, y, z : double;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
type Tvector = class
protected
coordinate: Tpoint3D;
public
function get_coord : Tpoint3D;
function get_module : double;
procedure normalization;
constructor birth( xx, yy, zz: double ); overload;
constructor birth( p: Tpoint3d ); overload;
end;
//-- векторные операции: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function summ_vectors( v_1, v_2: Tvector ): Tvector;
function dot_product( v_1, v_2: Tvector ) : double;
function mult_on_scal( k: double; v: Tvector ): Tvector;
//====================================================
implementation
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Tvector.get_coord: Tpoint3D;
78

II. Программная реализация математической модели
begin
result := coordinate;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function Tvector.get_module: double;
begin
result := sqrt( coordinate.x*coordinate.x
+ coordinate.y*coordinate.y
+ coordinate.z*coordinate.z );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
procedure Tvector.normalization;
var module: double;
begin
module := get_module;
if ( module <> 0.0 ) then
begin
coordinate.x := coordinate.x/module;
coordinate.y := coordinate.y/module;
coordinate.z := coordinate.z/module;
end;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
constructor Tvector.birth( xx, yy, zz: double );
begin
coordinate.x := xx;
coordinate.y := yy;
coordinate.z := zz;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
constructor Tvector.birth( p: Tpoint3d );
begin
coordinate.x := p.x;
coordinate.y := p.y;
coordinate.z := p.z;
end;
//====================================================
79

Математическое и компьютерное моделирование
0
function summ_vectors( v_1, v_2: Tvector ): Tvector;
var c1, c2: Tpoint3D;
begin
c1 := v_1.get_coord;
c2 := v_2.get_coord;
result := Tvector.birth(c1.x + c2.x, c1.y + c2.y, c1.z + c2.z);
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function dot_product( v_1, v_2: Tvector ): double;
var c1, c2: Tpoint3D;
begin
c1 := v_1.get_coord;
c2 := v_2.get_coord;
result := c1.x*c2.x + c1.y*c2.y + c1.z*c2.z;
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function mult_on_scal( k: double; v: Tvector ): Tvector;
var c: Tpoint3D;
begin
c := v.get_coord;
result := Tvector.birth( c.x*k, c.y*k, c.z*k );
end;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
end. // конец файла vectorUnit.pas
II.8.2. Класс TRay (луч)
// файл rayUnit.pas
unit rayUnit;
interface
uses vectorUnit, colorUnit;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Type Tray = class( Tvector )
protected
color : Tcvet;
8
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
