Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические материалы к ДЗ.doc
Скачиваний:
6
Добавлен:
09.02.2015
Размер:
472.06 Кб
Скачать

Var list : cList;

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

Constructor cList.Init;

Begin n:=0; End;

Procedure cList.Add(frp : cDecart);

Begin inc(n); a[n]:=frp; End;

Procedure cList.Draw;

Var i : integer;

Begin

if n=0 then Exit;

for i:=1 to n do a[i].Draw;

End;

Procedure cList.Rotation(da : real);

Var i : word;

Begin

if n=0 then Exit;

for i:=1 to n do a[i].Rotation(Pi/36);

End;

Procedure cList.Move;

Var i : word;

Begin

if n=0 then Exit;

for i:=1 to n do a[i].Move;

End;

Обработчик инициализации.

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

Листинг 18к. Обработчик инициализации списка.

procedure TForm1.InitList1Click(Sender: TObject);

const mx=75;// Масштаб задан константой

Var t0 : TPoint; tc : TRPoint; i:1..4;

begin

// Положение осей и стартовая точка

t0.X:=Form1.ClientWidth div 2;

t0.Y:=Form1.ClientHeight div 2;

tc.x:=-2;

tc.y:=MyTrace(-2);

// Инициализация координат и графика

dec:= cDecart.Init(t0.x, t0.Y, mx, Form1.Canvas);

trace:=cTrace.Init(t0.x, t0.Y, mx, Form1.Canvas,

-2, 2, MyTrace);

// Инициализация массива объектов - треугольников

tr[1]:=cTri.Init(t0.x, t0.Y, mx, Form1.Canvas,

0,0, 1,0, 0,1, trace, clRed);

tr[2]:=cTri.Init(t0.x, t0.Y, mx, Form1.Canvas,

0,0, -1,0, 0,1, trace, clBlue);

tr[3]:=cTri.Init(t0.x, t0.Y, mx, Form1.Canvas,

0,0, -1,0, 0,-1, trace, clGreen);

tr[4]:=cTri.Init(t0.x, t0.Y, mx, Form1.Canvas,

0,0, 1,0, 0,-1, trace, clYellow);

// Инициализация списка (контейнера)

list:=cList.Init;

// Сложим все объекты в контейнер

list.Add(dec);

list.Add(trace);

for i:=1 to 4 do list.Add(tr[i]);

// Рисование стартового положения списка

for i:=1 to 4 do list.Draw;

// Разрещение включения таймера

N2.Enabled:=true;

end;

Обработчик таймера.

Листинг 18л. Обработчик таймера.

procedure TForm1.Timer1Timer(Sender: TObject);

Var I : word;

Begin

// Рисуем список

list.Draw;

// Пересчет координат при вращении

list.Rotation(pi/36);

// Пересчет координат центра вращения

list.Move;

end;

Виртуальные методы базового класса.

Если не предпринять никаких действий, то при обращении к методам контейнера будут использоваться методы базового класса, так как в классе контейнера содержатся объекты базового класса. Иначе говоря, вместо рисования треугольников из cTri будут рисоваться оси из cDecart.

Чтобы использовались методы производных классов, надо в базовом классе все методы, которые необходимо перекрыть в производных классах, объявить виртуальными. Таких методов три

    1. Метод рисования Draw.

    2. Метод поворота Rotation.

    3. Метод перемещения Move.

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

Остальных методов в базовом классе нет, поэтому они должны быть добавлены, как правило, с пустыми реализациями (Begin End;), если, конечно, не требуется крутить и двигать оси координат.

Виртуальные методы в производных классах.

  • Класс cTri содержит все три виртуальных метода, и они должны быть объявлены как override.

  • Класс cTrace содержит только один «полноценный» перекрываемый метод Draw, а два остальных должны быть добавлены с пустой реализацией. Например, объявление в классе

Procedure Rotation(da : real); override;

Procedure Move;

Пустая реализация этих методов

Procedure cTrace.Rotation(da : real); Begin End;

Procedure cTrace.Move; Begin End;

Добавление новых объектов в композицию.

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

Добавление (удаление) объектов должно проводиться в тот же список, что и используется в обработчике таймера. Единственное условие, список к этому моменту должен существовать и заново инициализировать его ни в коем случае не надо.

Если необходимо сделать разный темп движения, объектов можно создать еще один список с новым таймером (и, конечно, с новым обработчиком)

Буферизация графического вывода

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

В DELPHI для этой цели предусмотрен специальный класс TBitmap, объекты которого также имеют свойство Canvas и, следовательно, обладают теми же методами рисования, что и визуальные компоненты.

Мы в учебном примере будем рассматривать одинарную буферизацию. В качестве видеобуфера будем использовать глобальную переменную

Picture : TBitmap;

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

Picture:=TBitmap.Create; // Инициализация буфера

Picture.Width:=2*t0.X; // Ширина

Picture.Height:=2*t0.Y; // Высота

При обращении к соответствующим конструкторам изменить имя переменной холста на

Picture.Canvas

После этих действий вывод будет происходить в буфер, а не на экран. Результат естественно виден не будет. Для вывода из буфера на экран достаточно выполнить копирование изображения на холст визуального компонента, например на форму

Form1.Canvas.Draw(0,0,Picture);

Литература.

  1. Алгоритмы. Просто как дважды два / И.В.Красиков, И.Е.Красикова. – М.: Эксмо, 2006. - 256с.

  2. Элементы графики в процедурном программировании на Туробо-Паскале. Ч.1:Учебно-методическое пособие / А.Ф.Меняев и др.; Под ред. Б.Г.Трусова. М.: Изд-во МГТУ им. Н.Э. Баумана, 2001. 44 с., ил.

  3. Элементы графики в процедурном программировании на Турбо-Паскале. Ч.2:Учебно-методическое пособие / А.Ф.Меняев и др.; Под ред. Б.Г.Трусова. М.: Изд-во МГТУ им. Н.Э. Баумана, 2002. 60 с., ил.

  4. Иванова Г.С. Основы программирования: Учебник для вузов. – М.: Изд-во МГТУ им. Н.Э. Баумана, 2001. – 392с.

  5. В.И. Смирнов. Курс высшей математики, том III, часть I, М., изд. «Наука», 1974 г., 324 стр.

1Для определения координаты точки пересечения хорды с осьюX(рис.6.1) целесообразно использовать уравнение прямой вида(f(x)-f(a))/(x-a)= (f(b)-f(a))/(b-a), гдеf(x)ордината любой точкиx,

принадлежащей хорде. Подставив в эту формулу c вместоx, с учетом того, чтоf(c)=0, можно получить выражение для вычисленияc.

2Такой способ разработки программ в литературе получил название «нисходящее программирование» или «пошаговой детализации» [4].