Эта статья является естественным продолжением предыдущей PolyLine и Polygon, и здесь мы рассмотрим ещё две процедуры графического модуля PascalABC.Net — DrawPolygon и FillPolygon, выясним, что между ними общего и в чем их отличия. Сначала опишем первую, а ниже займёмься второй. Начнем по порядку.
✎ **procedure** DrawPolygon(points: **array of** Point);
— Рисует замкнутую ломаную по точкам, координаты которых заданы в массиве points
Из определения подпрограммы видно, что процедура DrawPolygon — это замкнутая линия, имеющая некоторую толщину. Также следует заметить, что пространство внутри этой замкнутой будет пустым. Чтобы привести пример её использования, откроем среду PascalABC.Net и запуститим следующую программу, отвечающую за рисование четырехугольника с толщиной линии 10 пикселей.
uses
GraphABC;
var
P: array of point;
begin
SetWindowSize(450, 250); //Размеры окна
SetLength(P, 4); //Количество вершин ломаной
SetPenWidth(10); //Толщина линии ломаной
SetPenColor(clGreen); //Цвет ломаной
{ Задаем координаты вершин: }
p[0].X := 50; p[0].Y := 80;
p[1].X := 350; p[1].Y := 50;
p[2].X := 400; p[2].Y := 120;
p[3].X := 150; p[3].Y := 200;
DrawPolygon(P) //Рисуем ломаную
end.
**unit** GraphABC;
: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне**type** Point = System.Drawing.Point;
: Тип точки**procedure** SetWindowSize(w,h: integer);
: Устанавливает размеры клиентской части графического окна в пикселах**procedure** SetLength(**var** a: System.Array; n: integer);
: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться.**procedure** SetPenWidth(Width: integer);
: Устанавливает ширину текущего пера**procedure** SetPenColor(c: Color);
: Устанавливает цвет текущего пера Цвет:clGreen
- зеленый**procedure** DrawPolygon(points: **array** **of** Point);
: Рисует замкнутую ломаную по точкам, координаты которых заданы в массиве points
Разберем код по строкам:
Следует понимать, что пространство внутри DrawPolygon — пустое. Это значит, что использование кисти Brush для закрашивания внутренней части многоугольника бессмысленно. Этим процедура DrawPolydon кардинально отличается от заполненного (закрашенного) многоугольника Polygon в PascalABC.Net. Это НУЖНО продемонстрировать на примере.
Построим три многоугольника — два незакрашенных DrawPolygon, а между ними один закрашенный Polygon — таким образом, чтобы средняя фигура пересекалась с крайними. Скопируйте нижеприведенный код в PascalABC.Net и запустите:
uses
GraphABC;
var
P: array of point;
begin
SetWindowSize(500, 300); //Размеры окна
SetLength(P, 4); //Количество вершин
SetPenWidth(15); //Толщина линии ломаной
SetPenColor(clGreen); //Цвет ломаной
SetBrushColor(clOrange); //Цвет заливки
{ I. Координаты вершин ломаной: }
p[0].X := 50; p[0].Y := 50;
p[1].X := 200; p[1].Y := 20;
p[2].X := 250; p[2].Y := 100;
p[3].X := 150; p[3].Y := 180;
DrawPolygon(P); //Рисуем замкнутую ломаную
sleep(2000); //Пауза на 2 сек.
{ II. Координаты вершин многоугольника: }
p[0].X := 150; p[0].Y := 100;
p[1].X := 300; p[1].Y := 70;
p[2].X := 350; p[2].Y := 140;
p[3].X := 250; p[3].Y := 220;
Polygon(P); //Многоугольник
sleep(2000); //Пауза на 2 сек.
SetPenColor(clRed); //Меняем цвет ломаной
{ III. Координаты вершин ломаной: }
p[0].X := 250; p[0].Y := 50;
p[1].X := 400; p[1].Y := 20;
p[2].X := 450; p[2].Y := 100;
p[3].X := 350; p[3].Y := 180;
DrawPolygon(P) //Рисуем замкнутую ломаную
end.
**unit** GraphABC;
: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне**type** Point = System.Drawing.Point;
: Тип точки**procedure** SetWindowSize(w,h: integer);
: Устанавливает размеры клиентской части графического окна в пикселах**procedure** SetLength(**var** a: System.Array; n: integer);
: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться.**procedure** SetPenWidth(Width: integer);
: Устанавливает ширину текущего пера**procedure** SetPenColor(c: Color);
: Устанавливает цвет текущего пера Цвет:clGreen
- зеленый**procedure** SetBrushColor(c: Color);
: Устанавливает цвет текущей кисти Цвет:clOrange
- оранжевый**procedure** DrawPolygon(points: **array** **of** Point);
: Рисует замкнутую ломаную по точкам, координаты которых заданы в массиве points**procedure** Sleep(ms: integer);
: Делает паузу на ms миллисекунд**procedure** Polygon(points: **array** **of** Point);
: Рисует заполненный многоугольник, координаты вершин которого заданы в массиве points**procedure** Sleep(ms: integer);
: Делает паузу на ms миллисекунд**procedure** SetPenColor(c: Color);
: Устанавливает цвет текущего пера Цвет:clRed
- красный**procedure** DrawPolygon(points: **array** **of** Point);
: Рисует замкнутую ломаную по точкам, координаты которых заданы в массиве points Итак, смотрим основные моменты по строкам кода.
И что мы видим? Средняя фигура — залитый оранжевым многоугольник — покрывает собою ломаную слева, но не закрывается красной ломаной справа. Это и говорит о том, что DrawPolygon задает только границу многоугольника, Polygon — залитый, и в простом PascalABC аналогом ей является Polygon.
Наконец, важное уточнение: выше процедуру DrawPolygon мы называли многоугольником. Но это будет только тогда, когда вершины располагаются соответствующим образом. Вообще, данная подпрограмма рисует ломаную (замкнутую), и это нужно помнить.
Продемонстрируем это на примере случайно появляющихся ломаных — со случайным количеством вершин, случайного цвета и толщины (в заданных диапазонах). Если запустите следующую программу, то увидите, что получившиеся ломаные редко будут мноугольниками, так как из звенья практически всегда пересекаются, за исключением очень редких случаев. Все комментарии в коде программы.
uses
GraphABC;
var
points: array of point; //Массив точек
begin
LockDrawing; //Блокирует рисование до следующей перерисовки
repeat
var n := random(3, 20); //Размер массива - случайное число от 3 до 20
SetLength(points, n); //Устанавливаем размер массива равным n
SetPenColor(clRandom); //Цвет ломаной - случайный
SetPenWidth(random(1, 8)); //Толщина ломаной - случайное число от 1 до 8
randomize;
{ Определяем случайные координаты вершин ломаной: }
for var i := 0 to n - 1 do begin
points[i].X := random(20, WindowWidth - 20); //Координата X
points[i].Y := random(20, WindowHeight - 20) //Координата Y
end;
DrawPolygon(points); //Рисуем замкнутую ломаную
ReDraw; //Перерисовка графического окна
sleep(2000); //Пауза на 2 секунды
ClearWindow //Очищает графическое окно
until false //Бесконечный цикл
end.
**unit** GraphABC;
: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне**type** Point = System.Drawing.Point;
: Тип точки**procedure** LockDrawing;
: Блокирует рисование на графическом окне. Перерисовка графического окна выполняется с помощьюRedraw
**function** Random(maxValue: integer): integer;
: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2)**function** Random(a,b: integer): integer;
: Возвращает случайное целое в диапазоне от a до b.3)**function** Random: real;
: Возвращает случайное вещественное в диапазоне [0..1).**procedure** SetLength(**var** a: System.Array; n: integer);
: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться.**procedure** SetPenColor(c: Color);
: Устанавливает цвет текущего пера**function** clRandom: Color;
: Возвращает случайный цвет**procedure** SetPenWidth(Width: integer);
: Устанавливает ширину текущего пера**function** Random(maxValue: integer): integer;
: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2)**function** Random(a,b: integer): integer;
: Возвращает случайное целое в диапазоне от a до b.3)**function** Random: real;
: Возвращает случайное вещественное в диапазоне [0..1).**procedure** Randomize;
: Инициализирует датчик псевдослучайных чисел.2)**procedure** Randomize(seed: integer);
: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.**function** Random(maxValue: integer): integer;
: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2)**function** Random(a,b: integer): integer;
: Возвращает случайное целое в диапазоне от a до b.3)**function** Random: real;
: Возвращает случайное вещественное в диапазоне [0..1).**function** WindowWidth: integer;
: Возвращает ширину клиентской части графического окна в пикселах**function** Random(maxValue: integer): integer;
: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2)**function** Random(a,b: integer): integer;
: Возвращает случайное целое в диапазоне от a до b.3)**function** Random: real;
: Возвращает случайное вещественное в диапазоне [0..1).**function** WindowHeight: integer;
: Возвращает высоту клиентской части графического окна в пикселах**procedure** DrawPolygon(points: **array** **of** Point);
: Рисует замкнутую ломаную по точкам, координаты которых заданы в массиве points**procedure** Redraw;
: Перерисовывает содержимое графического окна. Вызывается в паре сLockDrawing
**procedure** Sleep(ms: integer);
: Делает паузу на ms миллисекунд**procedure** ClearWindow;
: Очищает графическое окно белым цветом**const** false = False;
: Представляет логическое значение. К стати, уберите 8-ю, 21-ю, 22-ю и 23-ю строчки кода и увидите интересную мозаику.
✎ **procedure** FillPolygon(points: **array of** Point);
— Заполняет многоугольник, координаты вершин которого заданы в массиве points
Из определения видно, что FillPolygon — закрашенный многоугольник, НЕ имеющий границы. Это значит, что если перед использованием данной процедуры мы постараемся задать толщину пера с помощью SetPenWidth(...)
, то никакой границы все равно не получится. Иными словами, если рассмотреть некий закрашенный многоугольник, то DrawPolygon рисует его границу, а FillPolygon — закрашивает внутреннюю часть.
Приведем пример пятиугольника, нарисованного с помощью FillPolygon. Скопируйте следующую программу в PascalABC.Net и запустите.
uses
GraphABC;
var
points: array of point; //координаты вершин многоугольника
begin
SetWindowSize(450, 250);
SetLength(points, 5); //задаем размер массива координат вершин
SetBrushColor(ClRed); //цвет области многоугольника
{ Задаем вершины многоугольника: }
//координаты 1-й вершины многоугольника:
points[0].X := 50;
points[0].Y := 50;
//координаты 2-й вершины многоугольника:
points[1].X := 350;
points[1].Y := 85;
//координаты 3-й вершины многоугольника:
points[2].X := 430;
points[2].Y := 130;
//координаты 4-й вершины многоугольника:
points[3].X := 370;
points[3].Y := 170;
//координаты 5-й вершины многоугольника:
points[4].X := 70;
points[4].Y := 220;
SetPenWidth(15); //Толщина линии - не отображается
SetPenColor(clGreen); //Цвет линии - не отображается
{ Строим многоугольник: }
FillPolygon(points)
end.
**unit** GraphABC;
: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне**type** Point = System.Drawing.Point;
: Тип точки**procedure** SetWindowSize(w,h: integer);
: Устанавливает размеры клиентской части графического окна в пикселах**procedure** SetLength(**var** a: System.Array; n: integer);
: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться.**procedure** SetBrushColor(c: Color);
: Устанавливает цвет текущей кисти Цвет:clRed
- красный**procedure** SetPenWidth(Width: integer);
: Устанавливает ширину текущего пера**procedure** SetPenColor(c: Color);
: Устанавливает цвет текущего пера Цвет:clGreen
- зеленый**procedure** FillPolygon(points: **array** **of** Point);
: Заполняет многоугольник, координаты вершин которого заданы в массиве points
В 13 - 26 строках мы задаем координаты многоугольника, а в 32-й строчке кода мы его рисуем, используя процедуру FillPolygon. НО обратите внимание: перед тем как нарисовать фигуру, в 28 и 29 строках мы задаем толщину и цвет линии, но на рисунке она НЕ ОТОБРАЖАЕТСЯ, то есть пятиугольник без границы. Это и не удивительно, поскольку FillPolygon рисует многоугольник без границы.
А теперь замените FillPolygon(points)
в 32 строке на Polygon(points)
, ничего больше не меняйте. Получим следующую картину:
Мы получили тот же пятиугольник, но с границей. Таким образом, здесь можно подытожить: Polygon — многоугольник с границей, FillPolygon — без неё.
Теперь возьмите программу выше с демонстрацией DrawPolygon и немного преобразуйте код:
Запускаем программу и смотрим на витражи:
Наконец, здесь всюду использовались пиксели (точки в графическом окне), имеющие координаты и цвет. Pixels очень часто можно встретить в разных сферах деятельности, таких как: фотография, а также во многих языках программирования при построении графиков функций или закрашивании фигур цветом. Это важнейшее понятие в графике и мы с ним не раз ещё встретимся.