Программная модель взаимного качения квадрата и эллипса по плоской поверхности
Курсовая работа, 06 Ноября 2013, автор: пользователь скрыл имя
Описание работы
Разработать программную модель взаимного качения квадрата и эллипса по плоской поверхности.
Цель работы
Ознакомиться с применением объектно-ориентированного программирования при создании больших программ.
Постановка задачи
В целом задача сводится к реализации вращения квадрата и эллипса вокруг заданной оси и перемещения оси вращения.
Содержание работы
Задание………………………………………………………..……...3
Цель работы…………………………………………………...……..3
Постановка задачи…………………………………………..……….3
Анализ и разработка алгоритма……………………………..……..3
Алгоритм программы…………………………………………...…..8
Текст программы……………………………………………...……..9
Результаты моделирования программы на ЭВМ……………..….16
Вывод...………………………………………………….…………...17
Литература………………………………………………….……….18
Файлы: 1 файл
Отчет.doc
— 151.50 Кб (Скачать файл)
Содержание
Задание………………………………………………………..
Цель работы…………………………………………………
Постановка задачи…………………………………
Анализ и разработка алгоритма……………………………..……..3
Алгоритм программы…………………………………………...….
Текст программы……………………………………………...…
Результаты моделирования программы на ЭВМ……………..….16
Вывод...………………………………………………….……
Литература………………………………………………….
Задание
Разработать программную модель взаимного качения квадрата и эллипса по плоской поверхности.
Цель работы
Ознакомиться с применением объектно-ориентированного программирования при создании больших программ.
Постановка задачи
В целом задача сводится к реализации вращения квадрата и эллипса вокруг заданной оси и перемещения оси вращения.
Анализ и разработка алгоритма
В результате выполнения программы на экране должно быть следующее:
Здесь К – это ось вращения квадрата, а Э – ось вращения эллипса.
Квадрат совершает обкат по поверхности эллипса. Основными структурными элементами (объектами) этого изображения являются точки и линии, и из них могут быть построены квадрат и эллипс и скомпонована вся сцена на экране, причем эти элементы образуют следующую иерархию:
Опишем эти объекты в соответствии с положениями ООП-программирования.
- Объект типа TPoint является точкой с координатами x,y вещественного типа и цветом Pcolor. Вещественный тип координат точки определяется тем, что этот объект предназначен для описания вершин квадрата и эллипса, а при вращении они могут принимать вещественные значения. Кроме очевидных необходимых методов Init, Show и Destructor добавим в их число и виртуальный метод Rotate реализующий плоское вращение точки вокруг заданной оси. Вращение точек вокруг заданной оси вращения осуществляется по формуле:
,где х0 , у0 – начальные координаты точки; х, у – координаты после поворота; а – угол поворота; OsX, OsY – координаты оси вращения.
Координаты оси вращения имеют вещественный тип и задаются извне (являются входными параметрами метода). Вещественные значения координат оси обусловлены тем, что длина отрезков, из которых состоит эллипс, может быть как целой, так и вещественной.
Методы TPoint достаточно простые: Constructor Init заполняет О-поля объекта; процедура Rotate, как описано выше вычисляет новые координаты точки по формулам геометрического поворота вокруг заданной оси на угол step, величина которого зависит от требуемой скорости вращения объекта и процедура Show скорее служит прототипом для дальнейшего наследования, чем для самостоятельного использования.
- Изображение эллипса может быть получено с помощью стандартной для модуля graph процедуры Ellipse, но построенный таким образом эллипс невозможно вращать, поэтому будем рассматривать его как многоугольник и строить с помощью процедур moveto и lineto по координатам вершин. Таким образом объект типа TEllipse конструируется из точек типа TPoint, количество которых определяется значением константы det, и переменной EColor для задания его цвета а его виртуальные методы Show и Rotate обеспечивают полиморфические свойства отображения и поворота. Координаты вершин вычисляются по формулам:
x=a*cos(t); y=b*sin(t), t=
где а и b – горизонтальный и вертикальный радиусы эллипса, а t вычисляется в зависимости от номера точки i и значения константы det. Процедура инициализации располагает центр эллипса в верхнем левом углу экрана.
- Объект типа TLine наследует все поля и методы TPoint, но перекрывает своими виртуальными методами Show и Rotate соответствующие методы родителя. Кроме унаследованных полей x и y, этот тип содержит два поля pn и pk типа TPoint, которые являются объектами и описывают две точки, задающие отрезок прямой на плоскости – будущую сторону квадрата. Виртуальные методы Show и Rotate позволяют отображать этот отрезок на экране цветом Lcolor и поворачивать его вокруг заданной оси. На первый взгляд, непонятна роль унаследованных полей x и y. Тем более, что можно было в типе TLine обойтись только одним полем pn, а координаты конца отрезка поместить в x и y. Однако, такой подход привел бы к разным синтаксическим конструкциям при обращении к начальной и конечной точкам отрезка, что повлияло бы на единообразие стилистики программы и затруднило бы ее восприятие. Кроме того, потомки данного типа могут использовать эти поля для своих специфических нужд, например, помещая в них координаты середины отрезка.
- Объектный тип TSquare (квадрат) конструируется из 4-х отрезков типа ТLine, длины стороны квадрата as и переменной Scolor для задания его цвета, а виртуальные методы Show и Rotate обеспечивают его полиморфические свойства отображения и поворота. Процедура инициализации располагает квадрат в верхнем левом углу экрана.
- Тип TScreen, находясь на самом нижнем уровне иерархии, описывает самый сложный объект – экран, со всеми его «действующими лицами»: катящимся эллипсом, катящимся по поверхности эллипса квадратом и поверхностью качения. Этот тип включает в себя эллипс, унаследованный из родительского типа, объект типа TSquare, О-поля для задания положения и цвета поверхности качения (поля Gdisp и Gcolor) и соответствующий метод DrawGround ее прорисовки на экране, поля line0, sides0 для сохранения предыдущих координат эллипса и квадрата, а также поля nom, OsXЕ,OsYЕ для номера точки эллипса, являющейся текущей осью вращения квадрата и текущих координат положения оси вращения эллипса соответственно. Методы ShiftOsXY и ShiftOsXYЕ отвечают за своевременное перемещение осей вращения квадрата и эллипса при качении и являются виртуальными, поскольку в потомках может возникнуть необходимость их модификации. Метод ShiftOsXYЕ перемещает ось вращения эллипса при достижении какой-либо из его точек поверхности качения. Метод ShiftOsXY контролирует контакт эллипса со сторонами квадрата. Для определения момента входа эллипса в пределы квадрата после очередного поворота его на небольшой угол step проводятся испытания всех точек эллипса на предмет входа их в пределы кавдрата. С этой целью вычисляются координаты каждой из этих точек в локальной системе координат X10Y1 квадрата. Для этого используются методы CalcABC и Dist. В методе CalcABC вычисляются параметры прямой Ax+By+C=0 – одной из осей локальной системы координат X10Y1 (линии, проходящей через центры противоположных сторон квадрата) по формулам:
A=yk - yn; B := xn - xk; C := xk * yn - xn * yk,
где xn, yn, xk, yk – координаты начала и конца отрезка прямой.
В методе Dist вычисляется расстояние (координата) точки (вершины эллипса) до соответствующей оси по формуле:
Dist= ,
Если обе полученные координаты по абсолютной величине меньше половины длины стороны квадрата, то данная точка эллипса входит в пределы квадрата, поэтому ось вращения перемещается в эту вершину эллипса. Факт смены оси вращения отмечается в результате функции ShiftOsXY значением True. Метод Rotateall обеспечивает вращение квадрата и эллипса вокруг точки вращения эллипса. Метод Go реализует продвижение изображения на один кадр при срабатывании таймера и регенерацию сцены при достижении эллипсом края окна.
Алгоритм программы
Блок-схема основной процедуры программы TScreen.go:
Текст программы
program Kursovik;
uses
Forms,
Kurspas in 'Kurspas.pas' {Form1},
ElSq in 'ElSq.pas' {Form2};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
unit Kurspas;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ElSq;
Const
sizeSq = 100; { размер квадрата }
colorEl = clBlue; {цвет эллипса}
colorSq = clYellow; { цвет квадрата }
colorG = ClGreen; { цвет поверхности качения }
type {описание формы}
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
Button2: TButton;
Timer1: TTimer;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
Var screen: TScreen; {определение объекта типа TScreen}
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); {при нажатии кнопки Go}
begin
timer1.Enabled:=true; {активировать таймер}
end;
procedure TForm1.Button2Click(Sender: TObject); {при нажатии кнопки Exit}
begin
screen.Done; {вызвать деструктор}
Close; {завершить выполнение приложения}
end;
procedure TForm1.Timer1Timer(Sender: TObject); {при срабатывании таймера}
begin
Screen .Go; {запустить процедуру анимации экрана}
end;
procedure TForm1.FormCreate(Sender: TObject); {при запуске приложения}
begin
Screen.Init(sizeSq, colorEl, colorSq, colorG, Image1.height-30,Image1 );
{инициализировать объект Screen}
end;
procedure TForm1.Button3Click(Sender: TObject); {при нажатии кнопки Stop}
begin
timer1.Enabled:=false; {остановить таймер}
end;
end.
unit ElSq;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
Const
det = 36; {количество вершин для построения эллипса}
xrad = 40; {горизонтальный радиус эллипса}
yrad = 25; {вертикальный радиус эллипса}
kv = 4; {количество сторон квадрата}
speed1 = 0.9; {скорость вращения эллипса}
speed = 1.5; {скорость вращения квадрата}
one = pi/180; {один градус в радинах}
step = one*speed; {шаг поворота квадрата}
step1 = one*speed1; {шаг поворота эллипса}
Type TPoint = Object {О-тип точка}
x,y :Real; {координаты точки}
Pcolor :Byte; {цвет точки}
Constructor Init ( xx,yy :Real; col :Byte );
Procedure Rotate ( xOs, yOs, spd :real ); Virtual;
Procedure Show ( col :Byte; var image1:TImage ); Virtual;
Destructor Done;
End;
TSide = array [1..det] of TPoint; {тип для описания вершин эллипса}
TEllipse=Object ( TPoint ) {О-тип эллипс}
line :TSide; {вершины эллипса}
EColor :Byte; {его цвет}
Constructor init (colE :byte);
procedure Rotate (xOsE, yOsE, spd:real); Virtual;
Procedure Show (col:Byte; var image1:TImage); Virtual;
Destructor Done;
end;
TLine = Object ( TPoint ) {О-тип отрезок}
pn, pk :TPoint; {начальная и конечная точки отрезка}
Lcolor :Byte; {его цвет}
Constructor Init ( x1,y1,x2,y2 :Real; col :Byte );
Procedure Rotate ( xOs, yOs, spd :real ); Virtual;
Procedure Show ( col :Byte; var image1:TImage ); Virtual;
Destructor Done;
End;
TSides = Array [ 0..kv-1 ] Of TLine; {тип для описания сторон квадрата}
TSquare = Object ( TLine ) {О-тип квадрат}
as :Byte; {длина стороны квадрата}
Sides :TSides; {стороны квадрата}
Scolor :Byte; {его цвет}
Constructor Init ( aa, colK :Byte );
Procedure Rotate ( xOs, yOs, spd :real ); Virtual;
Procedure Show ( col :Byte; var image1:TImage ); Virtual;
Destructor Done;
End;
TScreen = Object ( TEllipse ) {О-тип сцена}
image1 :TImage; {адрес картинки}
Elps :TEllipse; {эллипс}
Sqre :Tsquare; {квадрат}
Gdisp :Integer; {смещение поверхности качения}
Gcolor :TColor; {цвет поверхности качения}
line0 :TSide; {переменные для запоминание текущего положения фигур}
sides0 :TSides;
OsXE,OsYE,nom :Integer; {переменные для хранения координат осей вращения}
Constructor Init ( aa:Byte; colE, colK, colG :TColor; dG :Integer; var image:TImage );
Function ShiftOsXY :Boolean; Virtual;
Function ShiftOsXYE :Boolean;
Procedure CalcABC( Var S1,S2 :TLine; Var A,B,C :Real );
Function Dist( A,B,C, xx,yy :Real) :Real;
Procedure Rotateall(xOs,yOs:Integer; spd:real);
Procedure Go; Virtual;
Procedure DrawGround; Virtual;
Destructor Done;
End;
{TForm2 = class(TForm)
private }
{ Private declarations}