Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

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




Для выполнения этого домашнего задания необходима тщательная проработка предыдущего практикума, где рассмотрены основные приемы объектно-ориентированного программирования.

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

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

В этом и последующих практикумах будет рассматриваться фигура, состоящая из 4 прямоугольных равнобедренных треугольников.

Последовательность разработки.

Этап 1. Выбор области рисования и положения системы координат. На этом этапе создается базовый класс cDecart. Его объявление приведено ниже.

Листинг 18а. Объявление класса cDecart.

Type

TRPoint=record

x, y: real;

end;

cDecart=class

Protected

t0: TPoint;

mx: real;

cnv: TCanvas;

Public

Constructor Init(fx0, fy0: integer;

fmx: real;

fcnv: TCanvas);

Procedure Draw;

Function tpix(tr: TRPoint):TPoint;

end;

Реализация методов класса.

Procedure cDecart.Draw;

Const border=20;

Begin

// Добавлена очистка области рисования (фрагмент ниже)

cnv.Brush.Color:=clWhite;

cnv.Pen.Color:=clWhite;

Cnv.Rectangle(border, border,

2*t0.x-border, 2*t0.y-border);

// Далее по тексту рисование осей координат, как и раньше

..........

// Реализация функции пересчета

Function cDecart.tpix(tr: TRPoint):TPoint;

Begin

Result.X:=t0.X + round(mx*tr.x);

Result.Y:=t0.Y - round(mx*tr.y);

End;

Этап 2. Проектирование производного класса «закрашенный треугольник» с вершинами apex, центром вращения tc и цветом cl. Пока все очень упрощенно с конструктором из декартовых координат для данного примера.

Листинг 18б. Объявление класса cTri.

Type cTri=class(cDecart)

apex: array[1..3] of TRPoint;

tc: TRPoint;

cl: TColor;

Public

Constructor Init(fx0, fy0: integer;

fmx: real;

fcnv: TCanvas;

X1, y1, x2, y2,

x3, y3: real;

ftc: TRPoint;

fcl: TColor);

Procedure Draw;

end;

Реализация конструктора и методов.

Constructor cTri.Init(fx0, fy0: integer;

fmx: real; fcnv: TCanvas;

x1, y1, x2, y2, x3, y3: real;

ftc: TRPoint; fcl: TColor);

Begin

inherited Init(fx0, fy0, fmx, fcnv);

apex[1].x:=x1; apex[1].y:=y1;

apex[2].x:=x2; apex[2].y:=y2;

apex[3].x:=x3; apex[3].y:=y3;

tc:=ftc; cl:=fcl;

End;

Напомню, что тип TPoint, который используется в Polygon, взят из WINDOWS, а тип TRPoint объявлен в UDecart

Procedure cTri.Draw;

Var t: array[1..3] of TPoint; i: byte;

Begin

// Пересчет от реальных декартовых координат на

// пиксельные - экранные. Вот для чего нужна

// наследуемая функция tpix.

for i:=1 to 3 do t[i]:=tpix(apex[i]);

// Установим цвета и рисуем

cnv.Pen.Color:=cl;

cnv.Brush.Color:=cl;

cnv.Polygon(t);

End;

Тестирование классов cDecart и cTri.

Для тестирования создадим обработчик кнопки меню и просто нарисуем прямо на форме треугольник с осями координат.

Листинг 18в. Тестирование классов.

procedure TForm1.N1Click(Sender: TObject);

Var t0: TPoint; tc: TRPoint; tri:cTri;

Begin

t0.X:=Form1.ClientWidth div 2;

t0.Y:=Form1.ClientHeight div 2;

tc.x:=0.0;

tc.y:=0.0;

cDecart.Init(t0.x, t0.Y, 100, Form1.Canvas).Draw;

tri:=cTri.Init(t0.x, t0.Y, 100, Form1.Canvas,

0,0, 1,0, 0,1, tc, clRed);

tri.Draw;

end;

Результат тестирования показан на рис. 18а.

Рис.18а. Примерный вид формы с результатом тестирования.

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

Этап 3. Плоское движение раскладывается на вращательное вокруг центра вращения и поступательное. Метод вращения не рисует повернутый треугольник, он лишь пересчитывает декартовы координаты его вершин. В списке параметров метода передается угол da, на который должен быть повернут треугольник. Объявление в классе (интерфейс метода)

Procedure Rotation(da: real);

Вращение плоской фигуры удобнее всего описывать в полярной системе координат. Более того, иногда в данных класса бывает целесообразно хранить координаты точек в обеих системах, но мы этого делать не будем (оставим для зачета).

Листинг 18г. Реализация метода Rotation.

Procedure cTri.Rotation(da: real);

Var i: byte; r, a: real;

Begin

for i:=1 to 3 do

Begin

r:=sqrt(sqr(apex[i].x) + sqr(apex[i].y));

// Надо отдельно рассмотреть случаи 1) нормальный

if apex[i].x > 0 then

a:=arctan(apex[i].y/apex[i].x);

// 2)

if apex[i].x < 0 then a:=???

// 3а) и 3б)

if apex[i].x = 0 then

if apex[i].y >= 0 then a:=???

else a:=???;

// Наращивание полярного угла

a:=a+da;

// Обратный пересчет на новые декартовы координаты

apex[i].x:=r*cos(a);

apex[i].y:=r*sin(a);

end;

End;

Для случаев, помеченных знаками вопроса, придется вспомнить школьную программу по тригонометрии. На всякий случай вот подсказка: функция arctan() «правильно» работает только в первой и четвертой четверти. На рис.18б представлен результат двух вызовов метода рисования треугольников, между которыми находится вызов метода пересчета.

Рис.18б. Последовательное рисование исходного и повернутого треугольников (см. листинг 18д).

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...