Материал Уч. Д2, необходимый для написания работы –
Глава 3, пп. 1-3, Глава 4, пп. 1-2
Перечень основных компонент, необходимых для выполнения работы
TFORM, TLABEL, MessageDlg, MessageBox
Пример разработки приложения с минимальной функциональностью.
Ниже приведена программа, обладающая следующей функциональностью. Имеется меню, содержащее пункты – Работа и О программе,
Подпункты меню Работа позволяют работать с графическими объектами Точка, Окружность, Многоугольник, связанных в иерархию наследованием (отдельный модуль Unit3). При этом работа с объектом осуществляется единообразно – с использованием указателя на базовый класс. Намеренно не используется механизм динамического определения типа объекта (а вводится индекс объекта в иерархии), эта возможность оставлена для самостоятельного использования в заданиях для сильных студентов.
Диалоговое окно О программе реализовано как отдельный модуль (немодальный диалог) и (вследствие его простоты) в методичке не показан, но доступен на диске.
unit Unit1; // Работа с формой главного окна приложения
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus,Unit2,Unit3,ExtCtrls, ComCtrls, StdCtrls;
Type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
point: TMenuItem;
circle: TMenuItem;
N_angle: TMenuItem;
N6: TMenuItem;
exit: TMenuItem;
Public
procedure exitClick(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure pointClick(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure circleClick(Sender: TObject);
procedure N_angleClick(Sender: TObject);
procedure FormPaint(Sender: TObject);
end;{class}
Var
Form1: TForm1;
Point1: TMyPoint;
FlagPoint: Boolean; //Активность
ObjectType:integer;
Implementation
{$R *.dfm}
{Обработка пункта меню «Выход»}
procedure TForm1.exitClick(Sender: TObject);
begin
Close; {Окончание работы}
end; {proc}
{Обработка пункта меню «О программе»}
procedure TForm1.N2Click(Sender: TObject);
begin
Form2.Show;
end; {proc}
{Обработка пункта меню «Точка»}
procedure TForm1.pointClick(Sender: TObject);
begin
ObjectType:=1;
Point1:=TMyPoint.Create(100,100,clRed);// создана красная точка
Point1.Show; // показать
FlagPoint:=True; // сделать активной для клавиатуры
end; {proc}
{Обработка события на форме – нажатие на клавиатуре }
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
i:integer;
begin
if(FlagPoint) then begin
// Если точка активна, то клавиатурные нажатия
// изменяют ее поля так
// пробел - изменение цвета по модулю 16
// управление курсором - перемещение точки
case Key of
VK_Space: begin
Point1.Hide; Point1.Color:=Point1.Color+255; Point1.Show;
end;
Vk_Right: begin
Point1.Hide; Point1.X:= (Point1.X+1) mod Form1.Width; Point1.Show;
end;
Vk_Left: begin
Point1.Hide; Point1.X:= (Point1.X-1) mod Form1.Width;
if(Point1.X<0) then Point1.X:= Point1.X+Form1.Width;
Point1.Show;
end;
Vk_Up: begin
Point1.Hide; Point1.Y:= (Point1.Y-1) mod Form1.Height;
if(Point1.Y<0) then Point1.Y:= Point1.X+Form1.Height;
Point1.Show;
end;
VK_Down:begin
Point1.Hide; Point1.Y:= (Point1.Y+1) mod Form1.Height; Point1.Show;
end;
VK_Escape:begin
Point1.Hide; Point1.Free; // Деструктор
FlagPoint:=False; // неактивна
ObjectType:=0;
end;
end;{case}
if ObjectType>1 then begin
// доступны рястяжения - сжатия
case Key of
VK_F1: begin
(Point1 as Tcircle).Expand(5);
end;
VK_F2: begin
(Point1 as Tcircle).Contract(5);
end;
end;//case
end;
if ObjectType>2 then begin
// доступны вращения
case Key of
VK_F3: begin
(Point1 as TPoligon).Rotate(Pi/20);
end;
VK_F4: begin
(Point1 as TPoligon).Rotate(-Pi/20);
end;
end;//case
end;
end; {if}
end;{proc}
{Обработка пункта меню «Окружность»}
procedure TForm1.circleClick(Sender: TObject);
begin
Point1:=TCircle.Create(100,100,50,clGreen);// создан зеленый круг
ObjectType:=2;
Point1.Show; // показать
FlagPoint:=True; // сделать активной для клавиатуры
end; {proc}
{Обработка пункта меню «Многоугольник»}
procedure TForm1.N_angleClick(Sender: TObject);
begin
Point1:=TPoligon.Create(100,100,50,6,clBlue);// создан синий шестиугольник
ObjectType:=3;
Point1.Show; // показать
FlagPoint:=True; // сделать активной для клавиатуры
end; {proc}
{Обработка события формы - перерисовка}
procedure TForm1.FormPaint(Sender: TObject);
begin
if (FlagPoint=True) and (ObjectType=3) then begin
(Point1 as TPoligon).Show;
end;
end; {proc}
end. {Unit1}
// ============ Второй модуль программы ========================
unit Unit3; // Пользовательская иерархия графических объектов
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus,ExtCtrls;
Type
// Наша декларация точки
// Основное - использование массива TForm.Canvas. Pixels[x,y]
//
TMyPoint = class {Объект}
public
X,Y: Integer;
Visible: Boolean; {свойство - Видимость !!!}
Color: TColor;
public
function GetX: Integer; {Получить координату Х}
function GetY: Integer; {Получить координату Х}
constructor Create(InitX, InitY: Integer;IColor:TColor);
destructor Free;virtual;
procedure Show;virtual; {Показать объект на экране}
procedure Hide;virtual; {Убрать объект с экрана }
function IsVisible: Boolean; {Проверить видимость объекта }
procedure MoveTo(NewX, NewY: Integer); { Переместить объект}
end;{class}
// Наша декларация круга
// Основное - использование виртуальных правил в модуле 1
//
TCircle = class (TMyPoint) {Объект круг - наследник точки}
R: Integer; { Его новое качество - радиус }
public
constructor Create(InitX, InitY: Integer; InitRadius: Integer;IColor:TColor);
destructor Free;override;
procedure Show; override;
procedure Hide; override; { Новое правило перекроет правило точки !!! }
procedure Expand(ExpandBy: Integer); {Правило Расшириться }
procedure Contract(ContractBy: Integer); {Правило Сжаться }
end; ;{class}
// Наша декларация правильного многоугольника
// Основное – использование массива TStrings для хранения точек и
// корректной перерисовки фигуры при смещении окна
TPoligon = class (TCircle) {Объект правильный многоугольник - наследник точки}
Points: array of TPoint;
NumOfVertex: integer; //число вершин
Phi: double; // начальный угол для одной из вершин (1)
public
constructor Create(InitX, InitY, IR,INum: Integer;IColor:TColor);
destructor Free;override;
procedure Recalculate;
procedure Show;override; { Новое правило перекроет правило точки !!! }
procedure Hide;override; { Новое правило перекроет правило точки !!! }
procedure Rotate(phi1: double); { Вращать}
end;{class}
Implementation
uses unit1;
// Реализация класса Point
constructor TMyPoint.Create(InitX, InitY: Integer;
IColor:TColor);
begin
X:=InitX; Y:=InitY; Visible := False;{ Первоначально точка невидима }
Color:=Icolor;
end; {proc}
destructor TMyPoint.Free;
begin
end; {proc}
function TMyPoint.GetX: Integer;
begin GetX := X; end; {proc}
function TMyPoint.GetY: Integer;
begin GetY := Y; end; {proc}
procedure TMyPoint.Show;
begin
Visible := True; { Делаем атрибут точки - видимая }
with Form1.Canvas do begin
{ Прорисовываем ее цветом }
// Когда "толстая" точка приведет к ошибке?
Pixels[X,Y]:=Color; Pixels[X+1,Y]:=Color;
Pixels[X-1,Y]:=Color; Pixels[X,Y+1]:=Color; Pixels[X,Y-1]:=Color;
end;
end; {proc}
procedure TMyPoint.Hide;
begin
Visible := False; { Атрибут точки - невидимая }
with Form1.Canvas do begin
{ Прорисовываем ее цветом фона окна }
Pixels[X,Y]:=clBtnFace; Pixels[X+1,Y]:=clBtnFace;
Pixels[X-1,Y]:=clBtnFace; Pixels[X,Y+1]:=clBtnFace; Pixels[X,Y-1]:=clBtnFace;
end;
end; {proc}
function TMyPoint.IsVisible: Boolean;
begin
IsVisible := Visible;
end; {proc}
procedure TMyPoint.MoveTo(NewX, NewY: Integer);
begin
Hide; { Спрятать объект. Заметьте, что это верно и для потомков!}
X := NewX; Y := NewY;
Show; { Показать объект. Заметьте, что это верно и для потомков!}
end; {proc}
//Реализация методов объекта Circle:
constructor TCircle.Create(InitX, InitY: Integer; InitRadius: Integer;IColor:TColor);
begin
inherited Create(InitX, InitY,IColor); { Вызвать конструктор родителя }
R := InitRadius; { Установить начальный радиус }
end; {proc}
destructor TCircle.Free;
begin
inherited Free;
end; {proc}
procedure TCircle.Show;
var
tmpcolor:TColor;
begin
tmpColor:=Form1.Canvas.Pen.Color; Form1.Canvas.Pen.Color:=Color;
Form1.Canvas.Ellipse(X-(R div 2),Y-(R div 2),X+(R div 2),Y+(R div 2));
Form1.Canvas.Pen.Color:=tmpColor;
Visible := True; { Атрибут объекта - видимый }
end; {proc}
procedure TCircle.Hide;
var
TmpColor: TColor;
begin
tmpColor:=Form1.Canvas.Pen.Color; Form1.Canvas.Pen.Color:=clBtnFace;
Form1.Canvas.Ellipse(X-(R div 2),Y-(R div 2),X+(R div 2),Y+(R div 2));
Form1.Canvas.Pen.Color:=tmpColor;
Visible := False; { Атрибут объекта - невидимый }
end; {proc}
procedure TCircle.Expand(ExpandBy: Integer);
begin
Hide; { Спрятать объект }
R := R + ExpandBy; { Увеличить радиус }
if R < 0 then R := 0;
Show; { Прорисовать с новым радиусом}
end; {proc}
procedure TCircle.Contract(ContractBy: Integer);
begin
Expand(-ContractBy); { Использовать расширение со знаком минус }
end; {proc}
//Реализация методов объекта Poligon
constructor TPoligon.Create(InitX, InitY, IR,INum: Integer;IColor:TColor);
var
i:integer;
begin
{ Вызвать конструктор родителя, черный круг}
inherited Create(InitX, InitY,IR, clBlack);
NumofVertex:=INum; // число вершин
Phi:=0; // начальный угол
SetLength(Points, NumofVertex); //установить размер массива
Recalculate;
end; {proc}
destructor TPoligon.Free;
begin
inherited Free;
Points:=nil;
end; {proc}
procedure TPoligon.Recalculate; // Пересчет координат вершин
var
i:integer;
begin
for i:=0 to NumofVertex do begin
Points[i].X:=trunc(X+R*Cos(phi+i*2*Pi/NumofVertex));
Points[i].Y:=trunc(Y+R*Sin(phi+i*2*Pi/NumofVertex));
end;
end; {proc}
procedure TPoligon.Show;
var
tmpcolor:TColor; i:integer;
begin
Recalculate;
tmpColor:=Form1.Canvas.Pen.Color; Form1.Canvas.Pen.Color:=Color;
Form1.Canvas.MoveTo(Points[0].x,Points[0].Y);
for i:=Low(Points)+1 to High(Points) do begin
Form1.Canvas.LineTo(Points[i].x,Points[i].Y);
end;
Form1.Canvas.LineTo(Points[0].x,Points[0].Y);
Form1.Canvas.Pen.Color:=tmpColor;
Visible := True; { Атрибут объекта - видимый }
end; {proc}
procedure TPoligon.Hide;
var
TmpColor: TColor;
i:integer;
begin
Recalculate;
tmpColor:=Form1.Canvas.Pen.Color; Form1.Canvas.Pen.Color:=clBtnFace;
Form1.Canvas.MoveTo(Points[0].x,Points[0].Y);
for i:=Low(Points)+1 to High(Points) do begin
Form1.Canvas.LineTo(Points[i].x,Points[i].Y);
end;
Form1.Canvas.LineTo(Points[0].x,Points[0].Y);
Form1.Canvas.Pen.Color:=tmpColor;
Visible := False; {Атрибут объекта - невидимый}
end; {proc}
procedure TPoligon.Rotate(phi1:double);
begin
Hide; {Спрятать объект}
phi:=phi+phi1;
Show; {Прорисовать с новым радиусом}
end; {proc}
end. {Unit3}
Примерный перечень заданий для выполнения студентами.
Реализовать следующие иерархии объектов и заданные методы для них. На примере этих объектов продемонстрировать позднее связывание и полиморфизм
1. Точка – дуга окружности – сектор.
Методы: движение, растяжение, сжатие.
2. Отрезок –
квадрат – закрашенный квадрат,
равносторонний треугольник
Методы: сжатие, растяжение, поворот, движение.
3. Точка – окружность – вписанный n-угольник
– описанный n-угольник
Методы: движение, растяжение, сжатие.
4. Список телефонов – отсортирован по номеру
– отсортирован по имени
Методы: вывод списка, поиск телефона, поиск абонента, добавление списка.
5. Коллекция графических объектов.
Методы: добавление элемента в колекцию, вывод на экран, запись в файл, чтение из файла.
6. Точка – единичные вектор – ортонормированный репер – 3-х мерный репер.
Методы – сдвиг, повороты, растяжение-сжатие.
7. Точка, окружность, эллипс:
Методы – рисование, стирание, движение, растяжение, сжатие, вращение.
8. Точка, окружность, правильный n-угольник вписанный в окружность.
Методы:движение, растяжение, сжатие, вращение.
9. Точка, окружность, Правильный n-угольник описанный около окружности: Методы: движение, растяжение, сжатие, вращение
10. Точка, окружность, Правильный звездный n-угольник вписанный в окружности: Методы: движение, растяжение, сжатие, вращение, изменение числа сторон
11. Функция одного аргумента (y=f(x))
Методы:табулирование, построение графика на отрезке [a,b], вычисление интеграла на отрезке [a,b], вычисление производной в точке x.
12. Комплексное число
Методы:вывод на экран (текстовый и графический), сложение, вычитание, умножение, деление.
13. Нелинейное уравнение: F(x) = 0, a =< x =< b.
Методы:Нахождение нулей, построение графика и табулирование функции F(x).
14. Дифференциальное уравнение: dx/dt = F(x,t), x(0) = x0, 0 <= t <= T
Методы:численное решение, построение графика функции x(t), вывод численных значений функции x(t) на экран и в файл.
15. Система линейных алгебраических уравнений (СЛАУ):
ввод исходных данных из текстового файла и с клавиатуры, решение, выдача решения на экран и в текстовый файл.
Вопросы для самопроверки
1. Какой толщины рисуется точка?
2. Чем отличается окно «О программе» в данной лабораторной работе от предыдущих?
3. Как вращается многоугольник?
4. Как исправить затирание объектов при наезде на них других объектов?
5. При каких действиях многоугольник показывается правильно, и когда затирается?
ЛАБОРАТОРНАЯ РАБОТА Л-2.6