Программная модель взаимного качения квадрата и эллипса по плоской поверхности

Автор работы: Пользователь скрыл имя, 06 Ноября 2013 в 10:43, курсовая работа

Описание работы

Разработать программную модель взаимного качения квадрата и эллипса по плоской поверхности.
Цель работы
Ознакомиться с применением объектно-ориентированного программирования при создании больших программ.
Постановка задачи
В целом задача сводится к реализации вращения квадрата и эллипса вокруг заданной оси и перемещения оси вращения.

Содержание работы

Задание………………………………………………………..……...3
Цель работы…………………………………………………...……..3
Постановка задачи…………………………………………..……….3
Анализ и разработка алгоритма……………………………..……..3
Алгоритм программы…………………………………………...…..8
Текст программы……………………………………………...……..9
Результаты моделирования программы на ЭВМ……………..….16
Вывод...………………………………………………….…………...17
Литература………………………………………………….……….18

Файлы: 1 файл

Отчет.doc

— 151.50 Кб (Скачать файл)


 

 

Содержание

Задание………………………………………………………..……...3

Цель работы…………………………………………………...……..3

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

Анализ и разработка алгоритма……………………………..……..3

Алгоритм программы…………………………………………...…..8

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

Результаты моделирования  программы на ЭВМ……………..….16

Вывод...………………………………………………….…………...17

Литература………………………………………………….……….18

 

Задание

Разработать программную модель взаимного качения квадрата и эллипса по плоской поверхности.

Цель работы

Ознакомиться с применением  объектно-ориентированного программирования при создании больших программ.

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

В целом задача сводится к реализации вращения квадрата и  эллипса вокруг заданной оси и перемещения оси вращения.

Анализ и разработка алгоритма

В результате выполнения программы  на экране должно быть следующее:


 


 

 


 

Здесь К – это ось  вращения квадрата, а Э – ось  вращения эллипса.

 

Квадрат совершает обкат  по поверхности эллипса. Основными структурными элементами (объектами) этого изображения являются точки и линии, и из них могут быть построены квадрат и эллипс и скомпонована вся сцена на экране, причем эти элементы образуют следующую иерархию:


 

 

 


 

 

 

 

Опишем эти объекты  в соответствии с положениями  ООП-программирования.

  • Объект  типа 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}

Информация о работе Программная модель взаимного качения квадрата и эллипса по плоской поверхности