Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Turbo Pascal / Методические указание / Синтез графических образов простыми средствами.DOC
Скачиваний:
17
Добавлен:
15.06.2014
Размер:
205.82 Кб
Скачать

8 Моделирование динамического процесса с анализом

комплекса граничных условий и состояния движущихся объектов

В приведенных выше примерах моделировалось лишь движение объектов как для набора материальных точек, но не рассматривались свойства самих объектов. Рассмотрим процесс с изменением свойств самого движущегося объекта.

{--------------------------------------------------------------------------------------

"Движение в лабиринте"

---------------------------------------------------------------------------------------}

Uses Crt, Graph;

Var Gd,Gm, _x,_y, lx,ly, xc,yc, dx,dy,

rx,ry, rx_old, ry_old, i,j: integer;

ix,iy: boolean;

begin Gd:=0; InitGraph(Gd,Gm,'c:\tp7\bgi');

Rectangle( 10,10, 600,350); { элементы лабиринта }

Rectangle( 90,90, 300,190);

Rectangle( 400,90, 450,290);

dx:= 4; dy:= 3; { составляющие начальной скорости объекта }

rx:=10; ry:=10; { начальные размеры объекта }

xc:=150; yc:=30; { начальные координаты объекта }

Ellipse(xc,yc, 0,360, rx,ry); { объект в начальном положении }

lx:= abs(dx)+1;

ly:= abs(dy)+1; { число пикселов по ходу движения объекта }

REPEAT

rx_old:=rx;{ запоминание размеров объекта }

ry_old:=ry;

_x:=dx div abs(dx); { текущие направления движения объекта }

_y:=dy div abs(dy);

iy:=false; ix:=false; { признаки удара о стенку }

for i:=1 to lx do

{ анализ пути объекта по горизонтали }

if GetPixel( xc+(rx+i)*_x, yc)>0

{ на пути вертикальная стенка}

then begin dx:=-dx; { смена знака горизонтальной скорости }

ix:=true; { признак удара о вертикаль }

if rx>1 then begin

inc(ry); dec(rx) end; { корректировка размеров объекта }

{ звук удара и прекращение анализа пути }

sound(300); delay(9); nosound; break end;

for i:=1 to ly do

{ анализ пути объекта по вертикали }

if GetPixel( xc, yc+(ry+i)*_y)>0

{ на пути горизонтальная стенка }

then begin dy:=-dy; { смена знака вертикальной скорости }

iy:=true;{ признак удара о горизонталь }

if ry>1 then begin

inc(rx); dec(ry) end; { корректировка размеров объекта }

sound(400); delay(9); nosound; break end;

if (not ix) and(not iy) then { Если не было удара о стенки, то анализируем возможность удара во внешний угол }

for i:=1 to lx do

for j:=1 to ly do

if( GetPixel( xc+(rx+i)*_x, yc+(ry+j)*_y)> 0)

{ удар во внешний угол} then begin

dy:=-dy; dx:=-dx; { смена знака обеих составляющих скорости }

sound(500); delay(9); nosound; break end;

{ стирание объекта }

SetColor( 0); Ellipse( xc,yc, 0,360, rx_old,ry_old);

inc(xc,dx); inc(yc,dy); { смена координат объекта }

{ вывод нового положения объекта }

SetColor(14); Ellipse( xc,yc, 0,360, rx,ry);

delay(30) until KeyPressed; CloseGraph end.

Смоделируем процесс, в котором определяющим является изменение свойств набора рассматриваемых однотипных объектов.

Выводится набор окружностей

случайного радиуса и расположения.

Затем радиусы окружностей начинают

возрастать ( рисунок 2).

При касании окружностей меньшая

уничтожается.

При касании края экрана центр

окружности начинает смещаться.

Рисунок 2

При составлении подобных программ для получения простой без перегрузки различными условиями модели важно корректно и полно определить набор свойств составляющих модель объектов.

{---------------------------------------------------------------------------------------

"Мыльные пузыри"

----------------------------------------------------------------------------------------}

Uses Crt,Graph;

Const N=50;{ количество объектов }

VAR Gx,Gy, Gm,Gd, i,j: integer; L: real;

stop: boolean; {признак остановки процесса}

r,dr, { размер объектов и скорость изменения размера}

xc,yc: { координаты центров объектов }

array[1..N] of longint;

good: array[1..N] of boolean; { признак существования объектов}

BEGIN Gd:=0; initgraph(Gd,Gm, 'с:\tp7\bgi');

Gx:=GetMaxX; Gy:=GetMaxY; Randomize;

{ установка начальных параметров объектов }

for i:=1 to N do begin

R[i]:= 5+random(10); { радиус }

dR[i]:= 1+random( 3); { скорость роста }

xc[i]:=R[i]+random(Gx-2*R[i]); { координаты центра }

yc[i]:=R[i]+random(Gy-2*R[i]);

good[i]:=true { признак существования объекта }

end;

stop:=false; { признак остановки процесса }

Repeat

for i:=1 to N do { перебор объектов }

if good[i] then begin

circle(xc[i],yc[i],R[i]); { вывод объектов }

for j:=1 to N do { анализ соседей "j" для выбранного объекта }

if(j<>i)and(good[j]) then begin

{ расстояние между центрами объектов }

L:=sqrt(sqr(xc[i]-xc[j])+sqr(yc[i]-yc[j]));

{ если происходит касание объекта "i" с объектом "j" большего радиуса, то рассматриваемый объект "i" уничтожается }

if(R[i]+R[j]+dR[i]+dR[j]>=L)

and(R[j]>=R[i]) then

begin sound(100); delay(10); nosound;

good[i]:=false; break end;

end{j};

{ при достижении края растущий объект отодвигается от этого края }

if(xc[i]-R[i]-dR[i]<= 0) then inc(xc[i],dR[i]);

if(yc[i]-R[i]-dR[i]<= 0) then inc(yc[i],dR[i]);

if(xc[i]+R[i]+dR[i]>=Gx) then dec(xc[i],dR[i]);

if(yc[i]+R[i]+dR[i]>=Gy) then dec(yc[i],dR[i]);

end{i};

{ увеличение размеров объектов с контролем максимального размера }

for i:=1 to N do begin

if good[i] then inc(R[i],dR[i]);

if 2*R[i]>Gy then stop:=true

end;

delay(100); ClearDevice

until (KeyPressed)or(stop) end.