Практикум 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 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|