Root /ArchiveAbout
()

Ломаная PolyLine и замкнутая Polygon

Ломаная PolyLine и замкнутая Polygon

На предыдущей странице Линии в паскаль мы рассматривали построение последовательных прямых линий, используя процедуры MoveTo и LineTo. Но зная координаты вершин ломаной (замкнутой или нет), того же можно добится с помощью процедур PolyLine и Polygon. Каким образом, и какое отличие между этими подпрограммами?

Процедура PolyLine рисования ломаной линии

PolyLineпроцедура, рисует ломаную линию по точкам, координаты которых заданы в массиве points. В PascalABC и PascalABC.Net эта процедура задается немного по-разному.

Сначала мы определим PolyLine в PascalABC и PascalABC.Net, а ниже приведем примеры.

PolyLine в PascalABC:

**procedure** PolyLine(**var** points: **array**[1..n] **of** Point; n: **integer**);

 — Строит ломаную по n точкам, координаты которых заданы в массиве **a** элементов типа Point, задаваемый с помощью записи:

type
  Point = record //Point типа запись
     x, y: Integer; //x, y - поля записи
end;

**type** Point = System.Drawing.Point;: Тип точки **type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 PolyLine в PascalABC.Net: 

**procedure** PolyLine(points: **array of** Point);

 — Рисует ломаную по точкам, координаты которых заданы в массиве points. То есть points – это динамический массив, для которого нужно предварительно задать размер, а тип Point описывать не нужно (это встроенный тип PascalABC.Net).

Здесь видно, что в PascalABC.Net процедура PolyLine имеет только один параметр - собственно сам массив точек points (в отличии от простого PascalABC, где есть ещё второй параметр – размер массива, или количество точек). Ещё нужно помнить, что в динамических массивах нумерация начинается с 0.

Построим пример ломаной линии из массива точек PolyLine в PascalABC:

uses
  graphABC;

type { Описание типа Point с полями x, y: }
  Point = record
    x, y: integer;
end;

var
  P: array[1..4] of Point; //Массив точек

begin
  SetPenColor(clGreen); //Цвет линий
  SetPenWidth(3); //Толщина линий
  p[1].x := 300; p[1].y := 100; //Координаты первой вершины
  p[2].x := 500; p[2].y := 200; //Координаты второй вершины
  p[3].x := 300; p[3].y := 400; //Координаты третьей вершины
  p[4].x := 150; p[4].y := 250; //Координаты четвертой вершины
  PolyLine(P, 4) //Рисуем ломаную по точкам из массива P
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **procedure** SetPenColor(c: ColorType);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Polyline(**var** points; n: integer);: Строит ломаную по n точкам, координаты которых заданы в массиве points элементов типа TPoint То самое получим при использовании MoveTo(x, y) и LineTo(x, y):

uses
  graphABC;

begin
  SetWindowSize(600, 450);
  SetPenColor(clGreen); //Цвет линий
  SetPenWidth(3); //Толщина линий
  MoveTo(300, 100); //Начальная позиция рисования
  LineTo(500, 200);
  LineTo(300, 400);
  LineTo(150, 250)
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **procedure** SetWindowSize(w,h: integer);: Устанавливает размеры клиентской части графического окна в пикселах **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** MoveTo(x,y: integer);: Устанавливает текущую позицию рисования в точку (x,y) **procedure** LineTo(x,y: integer);: Рисует отрезок от текущей позиции до точки (x,y). Текущая позиция переносится в точку (x,y) **procedure** LineTo(x,y: integer);: Рисует отрезок от текущей позиции до точки (x,y). Текущая позиция переносится в точку (x,y) **procedure** LineTo(x,y: integer);: Рисует отрезок от текущей позиции до точки (x,y). Текущая позиция переносится в точку (x,y) В обоих вариантах получим одинаковый результат:

Пример PolyLine в PascalABC

Приведем пример той же программы, но в PascalABC.Net:

uses
  graphABC;

var
  P: array of Point; //Массив точек

begin
  SetWindowSize(600, 450); //Устанавливаем размер окна
  SetPenColor(clGreen); //Цвет линий
  SetPenWidth(3); //Толщина линий
  SetLength(P, 4); //Устанавливаем размер массива points
  p[0].x := 300; p[0].y := 100; //Координаты первой вершины
  p[1].x := 500; p[1].y := 200; //Координаты второй вершины
  p[2].x := 300; p[2].y := 400; //Координаты третьей вершины
  p[3].x := 150; p[3].y := 250; //Координаты четвертой вершины
  PolyLine(P) //Рисуем ломаную по точкам из массива P
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **procedure** SetWindowSize(w,h: integer);: Устанавливает размеры клиентской части графического окна в пикселах **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** SetLength(var a: System.Array; n: integer);: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться. **procedure** Polyline(points: **array** **of** Point);: Рисует ломаную по точкам, координаты которых заданы в массиве points На странице Графики функций в паскале мы учились строить простейшие графики, используя процедуру Line для соединения точек графика. Приведем здесь пример ещё одного несложного графика на PascalABC.Net, но уже с использованием подпрограммы PolyLine. Комментарии в коде.

Процедура Polygon рисования многоугольника

Polygonпроцедура, рисует замкнутую ломаную в PascalABC и заполненный многоугольник в PascalABC.Net по точкам, координаты которых заданы в массиве points.

Определение:

Polygon в PascalABC:

**procedure** Polygon(**var** A: **array**[1..n] **of** Point; n: **integer**);

— Строит замкнутую ломаную по n точкам, координаты которых заданы в массиве **a** элементов типа Point. Здесь Point - тип точки в PascalABC.

Polygon в PascalABC.Net:

**procedure** Polygon(points: **array of** Point);

— Рисует заполненный многоугольник, координаты вершин которого заданы в массиве points. Здесь points - это динамический массив точек типа Point, имеющий поля X, Y (координаты точки в графическом окне). Point в PascalABC.Net - это встроенный тип данных (примитивный, базовый), то есть такой, описывать который не нужно.

Какое отличие Polygon от PolyLine? Отличие только в том, что в случае с Polygon первая точка замыкается с последней, и в результате получаем не просто ломаную линию, а замкнутую ломаную – многоугольник. Далее приводим серию примеров использвания процедуры Polygon в PascalABC и PascalABC.Net для рисования многоугольников.

Мгогоугольник в PascalABC

Рисуем треугольник в PascalABC:

uses
  graphABC;

type { Описание типа точки: }
  Point = record
    x, y: integer;
end;

var { Многоугольник имеет 3 вершины: }
  p: array[1..3] of Point;

begin
  { Координаты точек: }
  p[1].x := 100; p[1].y := 100;
  p[2].x := 500; p[2].y := 200;
  p[3].x := 300; p[3].y := 500;
  { Рисуем треугольник: }
  Polygon(p, 3)
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **procedure** Polygon(**var** a; n: integer);: Строит ломаную по n точкам, координаты которых заданы в массиве a элементов типа Point Рисуем заполненный четырехугольник в PascalABC:

uses
  graphABC;

type
  Point = record
    x, y: integer;
end;

var
  P: array[1..4] of Point; //Массив точек

begin
  SetPenColor(clGreen); //Цвет границы многоугольника
  SetPenWidth(3); //Толщина линий
  p[1].x := 300; p[1].y := 100; //Координаты первой вершины
  p[2].x := 500; p[2].y := 200; //Координаты второй вершины
  p[3].x := 300; p[3].y := 400; //Координаты третьей вершины
  p[4].x := 150; p[4].y := 250; //Координаты четвертой вершины
  Polygon(P, 4); //Рисуем ломаную по точкам из массива P
  FloodFill(350, 200, clRed)
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **procedure** SetPenColor(c: ColorType);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Polygon(**var** a; n: **integer**);: Строит ломаную по n точкам, координаты которых заданы в массиве a элементов типа Point **procedure** FloodFill(x,y: integer; c: ColorType);: Заливает область одного цвета цветом c, начиная с точки (x,y) Цвет: clRed - красный

Многоугольник в PascalABC.Net

Рисуем треугольник в PascalABC.Net:

uses
  graphABC;

var
  P: array of Point;

begin 
  { Длина массива давна количеству вершин многоугольника: }
  SetLength(P, 3);
  { Определяем координаты 3 точек: }
  p[0].x := 100; p[0].y := 50;
  p[1].x := 500; p[1].y := 200;
  p[2].x := 300; p[2].y := 400;
  { Рисуем многоугольник: }
  Polygon(P)
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **procedure** SetLength(**var** a: System.Array; n: integer);: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться. **procedure** Polygon(points: **array** **of** Point);: Рисует заполненный многоугольник, координаты вершин которого заданы в массиве points Рисуем закрашенный четырехугольник в PascalABC.Net:

uses
  GraphABC;

var
  points: array of point; //координаты вершин многоугольника
  
begin
  SetWindowSize(400, 300); //Размеры окна
  SetLength(points, 4); //задаем размер массива координат вершин
  SetPenColor(ClGreen); //цвет границы многоугольника
  SetPenWidth(5); //ширина границы многоугольника
  SetBrushColor(ClRed); //цвет области многоугольника
 { Задаем вершины многоугольника: }
   //координаты 1-й вершины многоугольника:
  points[0].X := 80;
  points[0].Y := 80;
   //координаты 2-й вершины многоугольника:
  points[1].X := 370;
  points[1].Y := 35;
   //координаты 3-й вершины многоугольника:
  points[2].X := 300;
  points[2].Y := 280;
   //координаты 4-й вершины многоугольника:
  points[3].X := 20;
  points[3].Y := 200;
  { Строим многоугольник: }
  Polygon(points);
  { Сохраняем изображение в файл: }
  SaveWindow('Закрашенный четырехугольник.jpg')
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **procedure** SetWindowSize(w,h: integer);: Устанавливает размеры клиентской части графического окна в пикселах **procedure** SetLength(**var** a: System.Array; n: integer);: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться. **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** SetBrushColor(c: Color);: Устанавливает цвет текущей кисти Цвет: clRed - красный **procedure** Polygon(points: **array** **of** Point);: Рисует заполненный многоугольник, координаты вершин которого заданы в массиве points **procedure** SaveWindow(fname: string);: Сохраняет содержимое графического окна в файл с именем fname Здесь мы сохранили результат изображения в графическом окне с помощью процедуры SaveWindow в файл с именем "Закрашенный четырехугольник.jpg" (этот файл будет находится в той же папке, куда вы сохраните код данной программы):

Закрашенный четырехугольник в Pascal

Закрашенные многоугольники в PascalABC.Net:

uses
  GraphABC;

var
  points: array of point;
  
begin
  var R := 150; //Радиус окружности
  SetWindowSize(2 * R + 40, 2 * R + 40); //Размеры окна
  { Координаты центра окружности, вокруг
  которой будем строить многоугольник: }
  var x0 := WindowWidth div 2;
  var y0 := WindowHeight div 2;
  var count := 0;
  repeat
    var n := random(3, 30); //количество вершин многоугольника
    SetLength(points, n); //задаем размер массива координат вершин
    randomize;
    { Задаем вершины многоугольника: }
    for var i := 0 to n - 1 do begin
      var alfa : real := 2 * pi * i / n; //угол повотота радиуса
       //координаты точки окружности, соответствующей углу alfa
      var x1 := x0 + round(R * cos(alfa));
      var y1 := y0 - round(R * sin(alfa));
       //координаты i-й вершины многоугольника:
      points[i].X := random(x1 - 15, x1 + 15);
      points[i].Y := random(y1 - 15, y1 + 15);
    end;
    SetPenColor(ClRandom); //цвет границы многоугольника
    SetPenWidth(random(1, 5)); //ширина границы многоугольника
    SetBrushColor(ClRandom); //цвет области многоугольника
    Polygon(points); //строим многоугольник
    inc(count); //увеличиваем количество многоугольников
    { Сохраняем рисунки многоугольников в файл: }
    SaveWindow('Закрашенный четырехугольник-' + count.ToString + '.jpg');
    sleep(2000); //задержка на 2 секунды
    ClearWindow //очищаем окно белым цветом
  until false { цикл будет бесконечным, поскольку условие после until всегда ложно }
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **procedure** SetWindowSize(w,h: integer);: Устанавливает размеры клиентской части графического окна в пикселах **function** WindowWidth: integer;: Возвращает ширину клиентской части графического окна в пикселах A **div** B - целочисленное деление А на В **function** WindowHeight: integer;: Возвращает высоту клиентской части графического окна в пикселах A **div** B - целочисленное деление А на В

  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 на массив может измениться.
  2. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности. **type** real;: Представляет число двойной точности с плавающей запятой.Размер: 8 байт Количество значащих цифр: 15 - 16 Диапазон значений: -1.8∙10308 .. 1.8∙10308 **function** Round(x: real): integer;: Возвращает x, округленное до ближайшего целого. **function** Cos(x: real): real;: Возвращает косинус числа x. **function** Round(x: real): integer;: Возвращает x, округленное до ближайшего целого. **function** Sin(x: real): real;: Возвращает синус числа x.
  3. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1).
  4. **function** Random(maxValue: integer): integer;: Возвращает случайное целое в диапазоне от 0 до maxValue - 1.2) **function** Random(a,b: integer): integer;: Возвращает случайное целое в диапазоне от a до b.3) **function** Random: real;: Возвращает случайное вещественное в диапазоне [0..1). **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера **function** clRandom: Color;: Возвращает случайный цвет **procedure** SetPenWidth(Width: 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). **procedure** SetBrushColor(c: Color);: Устанавливает цвет текущей кисти **function** clRandom: Color;: Возвращает случайный цвет **procedure** Polygon(points: **array** **of** Point);: Рисует заполненный многоугольник, координаты вершин которого заданы в массиве points **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 **procedure** SaveWindow(fname: string);: Сохраняет содержимое графического окна в файл с именем fname **procedure** Sleep(ms: integer);: Делает паузу на ms миллисекунд **procedure** ClearWindow;: Очищает графическое окно белым цветом **const** false = False;: Представляет логическое значение. Программа работает так: при запуске в графическом окне каждые 2 секунды появляются закрашенные многоугольники со случайным количеством вершин от 3 до 30 (строка 16 кода). Потом определяем координаты вершин правильного многоугольника, и вслед за этим находим вершины нужного нам многоугольника как случайное отклонение на 15 пикселей (строки 20 - 28). Далее рисуем многоугольник (строка 32) и сохраняем его изображение (строка 35).

Обратите внимание, что этот процесс запущен в бексонечном цикле (условие false на выходе цикла repeat-until всегда ложно, поэтому он никогда не остановится), поэтому остановить его нужно просто закрыв окно. А ещё важное: каждые две секунды у вас в папке с программой будет появляться новый файл изображения типа "Закрашенный четырехугольник-1.jpg", "Закрашенный четырехугольник-2.jpg", "Закрашенный четырехугольник-3.jpg" и т.д., и если вам будут не нужны эти рисунки, то их надо удалить. Вот примеры таких многоугольников (наведите мышкой на картинку и прокручивайте вперед-назад):

Наконец, хотелось бы отметить важное замечание относительно процедуры Polygon: в PascalABC она рисует незаполненный многоугольник, а в PascalABC.Net – заполненный. Это значит, что для закрашивания многоугольника в PascalABC нужно использовать процедуру FloodFill(x, y, Color: integer) заполнения замкнутой области цвета color начиная с точки (x, y), а в PascalABC.Net – только задать цвет кисти SetBrushColor(C: Color).