Разработка программы реализующей эмуляцию упругого столкновения мячей

Контрольная работа - Компьютеры, программирование

Другие контрольные работы по предмету Компьютеры, программирование

Постановка задачи

 

В прямоугольной рамке, равной поверхности экрана, движутся N мячей, радиусами r1,…,rn. Они соударяются между собой, ударяются о края рамки. Начальное положение и вектор скорости для каждого шара случайные. Написать программу, моделирующую и отображающую на экране их движение. Удары считать абсолютно упругими, силу трения не учитывать.

 

Спецификация

 

Входные данные:

Информация, вводимая в специальном окне: для каждого графического объекта задается радиус, составляющие.

Выходные данные:

Графический интерфейс в виде диалогового окна позволяющий добавлять мячи, под средством вызова специального диалогового окна, изменять данные прямо в процессе работы программы без ее остановки, прерывать программу.

Программа должна:

Реализовать перемещение n-ого количества мячей которые отталкиваются от границ заданной области и друг от друга согласно правилам упругого удара.

Методика решения

Написание программы производилось в три основных этапа: разработка иерархии классов, описание собственно алгоритма программы, разработка графического интерфейса и объединение двух первых пунктов в единое целое.

Задачу можно разбить на 3 блока:

Задание начальных параметров (который происходит в режиме диалога).

Непосредственно работы программы, т.е. реализация упругого столкновения мячей.

Возможность добавления объектов и изменения данных во время работы программы.

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

Непосредственно работа программы подразумевает графическое отображение на экране монитора столкновение мячей с границей определенной области и друг с другом. Алгоритм реализации данной части программы будет описан ниже.

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

 

Организация данных

 

В программе описано два класса TBall и TBalls.

Класс TBall содержит поля, методы и свойства.

Поля:

_x,_y:integer; - координаты центра мяча по x и y.

_rad:integer; - радиус мяча.

_color:integer;- цвет мяча.

_dx:integer; - вектор скорости по x.

_dy:integer;- вектор скорости по y.

Методы:Create(rad,color,dx,dy,x,y:integer); - создание объекта.Destroy; override; -уничтожение объекта.

Свойства, позволяющие считывать и устанавливать значения соответствующих полей:

property x:integer read _x write _x;y:integer read _y write _y;rad:integer read _rad write _rad;color:integer read _color write _color;dx:integer read _dx write _dx;dy:integer read _dy write _dy;

Класс TBalls содержит массив мячей, каждый из которых это объект класса TBall.

Поля::array[0..100] of TBall; - массив мячей.

num : integer;- количество элементов в массиве.

Методы присущие данному классу:

function Add(x,y,dx,dy,col,rad:integer):boolean;- добавить мяч.

function del(n:integer):boolean;- удалить мяч.GetData(i:integer):TBall;- метод чтения.SetData(i:integer; Value:TBall);- метод записи.

Свойство позволяет получить информацию об объекте:

property Items[i:integer]:Tball read GetData write SetData;

 

Описание алгоритма

 

Алгоритм определения расчета движения мячей после соударения друг с другом:

Во вложенном цикле сравниваем каждый мячик по отдельности со всеми последующими. Для этого определяем расстояние между координатами центров и сравниваем с суммой радиусов. Если расстояние между центрами становится меньше суммы радиусов тогда по правилу упругого удара, меняем вектор скорости одного с другим. И после этого они продолжают перемещаться уже с другими скоростями. При этом для того, что бы не возникало никаких ошибок при столкновении их друг с другом, к координатам по x и по y прибавляем значение вектора скорости на данную ось и перерисовываем. Это позволяет избежать залипания мячей друг в друге, из за различных значений векторов скорости одного и другого.

Алгоритм проверки на соударение каждого мяча с границами экрана:

Мы должны проверить на достижения мячом границ определенной площади экрана, для этого определяем его границу и сравниваем с количеством пикселей по данной оси. Если выполняется одно из условий тогда изменяем вектор скорости на противоположный по данной оси. И после проделываем тоже самое для следующего шарика. Также учитываем, что мяч может перескочить через границу из за большого значения вектора скорости, во избежание данного события сделаем также как и при столкновении мячей, друг с другом, т.е. откинем мяч назначение вектора скорости от границы по каждой оси при их столкновении.

 

Текст программы

 

Приведем описание классов:

unit Unit2;Windows, SysUtils, Classes, Graphics, Math;=class

_x,_y : integer;

_rad : integer;

_color : integer;

_dx : integer;

_dy : integer;Create(rad,color,dx,dy,x,y:integer);Destroy; override;x:integer read _x write _x;y:integer read _y write _y;rad:integer read _rad write _rad;color:integer read _color write _color;dx:integer read _dx write _dx;dy:integer read _dy write _dy;;=classGetData(i:integer):TBall;SetData(i:integer; Value:TBall);:array[0..100] of TBall;: integer;Create;Destroy; override;Add(x,y,dx,dy,col,rad:integer):boolean;del(n:integer):boolean;Items[i:integer]:Tball read GetData write SetData;;TBall.Create(rad,color,dx,dy,x,y:integer);

_x:=x;

_y:=y;

_rad :=rad;

_color:= color;

_dx := dx;

=0)thenbegin[num]:=TBall.Create(rad,col,dx,dy,x,y);:=num+1;:=true;:=false;;Tballs.del(n:integer):boolean;i:integer;(n<num)and(n>=0)thenbegin[n].Destroy;i:=ntonum-2do[i]:=Balls[i+1];:=num-1;:=true;:=false;">_dy := dy;;TBall.Destroy;;;TBalls.Create;:=0;;TBalls.Destroy;i:integer;i:=0 to num-1 do[i].Destroy;;;TBalls.GetData(i:integer):TBall;:=Balls[i];;TBalls.SetData(i:integer; Value:TBall);[i]:=Value;;Tballs.Add(x,y,dx,dy,col,rad:integer):