Root /ArchiveAbout
()

Процедуры DrawPolygon и FillPolygon

Процедуры DrawPolygon и FillPolygon

Эта статья является естественным продолжением предыдущей PolyLine и Polygon, и здесь мы рассмотрим ещё две процедуры графического модуля PascalABC.Net — DrawPolygon и FillPolygon, выясним, что между ними общего и в чем их отличия. Сначала опишем первую, а ниже займёмься второй. Начнем по порядку.

Процедура DrawPolygon построения замкнутой ломаной

**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 в PascalABC.Net

Разберем код по строкам:

Следует понимать, что пространство внутри 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 и Polygon в PascalABC.Net

Наконец, важное уточнение: выше процедуру 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

  1. **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);: Устанавливает ширину текущего пера
  2. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1).
  3. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.
  4. **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;: Возвращает ширину клиентской части графического окна в пикселах
  5. **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-ю строчки кода и увидите интересную мозаику.

Процедура FillPolygon заполнения многоугольника

**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 Демонстрация FillPolygon в PascalABC.Net

В 13 - 26 строках мы задаем координаты многоугольника, а в 32-й строчке кода мы его рисуем, используя процедуру FillPolygon. НО обратите внимание: перед тем как нарисовать фигуру, в 28 и 29 строках мы задаем толщину и цвет линии, но на рисунке она НЕ ОТОБРАЖАЕТСЯ, то есть пятиугольник без границы. Это и не удивительно, поскольку FillPolygon рисует многоугольник без границы.

А теперь замените FillPolygon(points) в 32 строке на Polygon(points), ничего больше не меняйте. Получим следующую картину:

Пятиугольник Polygon в PascalABC.Net

Мы получили тот же пятиугольник, но с границей. Таким образом, здесь можно подытожить: Polygon — многоугольник с границей, FillPolygon — без неё.

Теперь возьмите программу выше с демонстрацией DrawPolygon и немного преобразуйте код:

Запускаем программу и смотрим на витражи:

Наконец, здесь всюду использовались пиксели (точки в графическом окне), имеющие координаты и цвет. Pixels очень часто можно встретить в разных сферах деятельности, таких как: фотография, а также во многих языках программирования при построении графиков функций или закрашивании фигур цветом. Это важнейшее понятие в графике и мы с ним не раз ещё встретимся.