Root /ArchiveAbout
()

Кривая линия Curve

Кривая линия Curve

На предыдущих страницах мы научились соединять две точки отрезком, а также строить ломаные линии и замкнутые ломаные. Мы даже умеем заполнить цветом замкнутую ломаную, используя процедуру Polygon или FillPolygon. Но там ничего не говорилось о том, как нарисовать кривую линию в паскале. Ведь надо же иногда нарисовать кривую как бы от руки, не используя отрезков. В PascalABC.Net кривую линию можно нарисовать с помощью встроенной в графический модуль подпрограммы Curve.

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

— Рисует кривую по точкам, координаты которых заданы в массиве points

Как видно из определения, Curve – это процедура, в которую нужно передать параметр – массив точек points. Для рисования кривой с помощью процедуры Curve нужно выдержать последовательность действий:

Давайте продемонстрируем вышесказанное на примере. Возьмем 3 точки, через которые проведем кривую, предварительно задав произвольные координаты. Массив, в котором будут хранится координаты, позначим А; тогда длина массива будет задаваться с помощью процедуры SetLength(A,3). Первая точка будет иметь номер 0, вторая – 1, третья – 2 (А – динамический массив, нумерация ведется с 0). Все комментарии в коде программы:

uses
  GraphABC;

var
  A: array of point; //Массив A точек типа point

begin
  SetLength(A, 3); //Устанавливаем длину массива равной 3
  { Координаты первой точки: }
  a[0].X := 100; // X
  a[0].Y := 60; // Y
  { Координаты второй точки: }
  a[1].X := 250; // X
  a[1].Y := 300; // Y
  { Координаты третьей точки: }
  a[2].X := 400; // X
  a[2].Y := 60; // Y
  SetPenColor(clGreen); //Цвет кривой
  SetPenWidth(3); //Толщина кривой в пикселях
  Curve(A) { <== РИСУЕМ КРИВУЮ по точкам из массива A }
end.

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

Мы получили линию похожую на параболу, но это не парабола. Это видно из того, что её стороны немного загнуты в стороны. Но где находятся точки, через которые проведена наша кривая? Чтобы это увидеть, давайте в процессе построения предыдущего кода программы подпишем каждую точку номерами соотвественно 0, 1 и 2, поставив возле каждой из них маленькие кружечки.

Для рисования кругов используем процедуру Circle(x,y), а для надписи в графическом окне – TextOut(x,y,s), где x,y – координаты точки, s – строка для вывода. Вот что у нас получилось:

uses
  GraphABC;

var
  A: array of point; //Массив A точек типа point

begin
  SetLength(A, 3); //Устанавливаем длину массива равной 3
  { Координаты первой точки: }
  a[0].X := 100; // X
  a[0].Y := 60; // Y
  { Координаты второй точки: }
  a[1].X := 250; // X
  a[1].Y := 300; // Y
  { Координаты третьей точки: }
  a[2].X := 400; // X
  a[2].Y := 60; // Y
  SetPenColor(clBlue); //Цвет кривой
  SetPenWidth(2); //Толщина кривой в пикселях
  Curve(A); { <== РИСУЕМ КРИВУЮ по точкам из массива A }
  { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }
  { ~~~~~~~~~~~~ ПОДПИСЫВАЕМ ТОЧКИ КРИВОЙ ~~~~~~~~~~~~ }
  { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }
  { I. Устанавливаем параметры кружечков: }
  SetBrushColor(clYellow); //цвет кружечков
  SetPenColor(clBlack); //цвет границы кружечков
  SetPenWidth(1); //толщина границы кружечков
  { II. Рисуем кружечки: }
  Circle(a[0].X, a[0].Y, 4);
  Circle(a[1].X, a[1].Y, 4);
  Circle(a[2].X, a[2].Y, 4);
  { III. Устанавливаем параметры шрифта: }
  SetBrushColor(clTransparent); //цвет области подписи прозрачный
  SetFontSize(12); //размер шрифта
  SetFontColor(clRed); //цвет шрифта
  { IV. Выводим надписи: }
  TextOut(a[0].X+10, a[0].Y-10, '0');
  TextOut(a[1].X, a[1].Y+5, '1');
  TextOut(a[2].X+10, a[2].Y, '2')
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **procedure** SetLength(**var** a: System.Array; n: integer);: Устанавливает длину одномерного динамического массива. Старое содержимое сохраняется. Ссылка a на массив может измениться. **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clBlue - синий **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Curve(points: **array** **of** Point);: Рисует кривую по точкам, координаты которых заданы в массиве points **procedure** SetBrushColor(c: Color);: Устанавливает цвет текущей кисти Цвет: clYellow - жёлтый **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clBlack - черный **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Circle(x,y,r: integer);: Рисует заполненную окружность с центром (x,y) и радиусом r **procedure** Circle(x,y,r: integer);: Рисует заполненную окружность с центром (x,y) и радиусом r **procedure** Circle(x,y,r: integer);: Рисует заполненную окружность с центром (x,y) и радиусом r **procedure** SetBrushColor(c: Color);: Устанавливает цвет текущей кисти Цвет: clTransparent - прозрачный **procedure** SetFontSize(size: integer);: Устанавливает размер текущего шрифта в пунктах **procedure** SetFontColor(c: Color);: Устанавливает цвет текущего шрифта Цвет: clRed - красный **procedure** TextOut(x,y: integer; s: string);: Выводит строку s в прямоугольник к координатами левого верхнего угла (x,y) **procedure** TextOut(x,y: integer; s: string);: Выводит строку s в прямоугольник к координатами левого верхнего угла (x,y) **procedure** TextOut(x,y: integer; s: string);: Выводит строку s в прямоугольник к координатами левого верхнего угла (x,y) Кривая Curve в PascalABC.Net и точки, через которые она проходит

Для разнообразия цвет кривой изменен с зеленого на синий (строка 18 кода). На рисунке видно, как кривая Curve плавно проходит по точкам 0, 1 и 2, огибая их.

Хотелось бы ещё заметить, что в строке 33 для области вывода текста мы задали прозрачный цвет с помощью SetBrushColor(clTransparent). Но что такое область вывода текста? Это прямоугольник, в который выводится текст. Чем больше размер шрифта (FontSize), тем больший прямоугольник. И если нужно вывести текст на какой-то фигуре или рисунке так, чтобы он не закрывал собой рисунок, то для заливки кистью для текста нужно использовать прозрачный цвет clTransparent. Впрочем, измените этот цвет на clYellow (жёлтый), clRed (красный), clGreen (зеленый) или другой, и вы всё поймете сами.

Но что такое всего три точки? Давайте нарисуем кривую линию с помощью Curve, используя больше узловых точек. Для этого сгенерируем случайные координаты X и Y, вычисляя их не последовательно, как выше, а в цикле. Координаты возьмем такие, чтобы не выходить за пределы графического окна GraphABC.Net. Количество узловых точек возьмем тоже случайное, а в конце программы выведем на экран сообщение об этом количестве.

uses
  GraphABC;

var
  A: array of point; //Массив точек
  n: byte; //Количество точек кривой

begin
  randomize; 
  n := random(5, 20); //случайное количество точек от 5 до 20
  SetLength(A, n); //Устанавливаем длину массива
  { Заполняем массив точек А случайными координатами: }
  for var i := 0 to n - 1 do begin
    a[i].X := random(50, WindowWidth - 50); //координата X
    a[i].Y := random(50, WindowHeight - 50) //координата Y
  end;
  SetPenColor(clGreen); //Цвет кривой
  SetPenWidth(3); //Толщина кривой в пикселях
  Curve(A); { <== РИСУЕМ КРИВУЮ по точкам из массива A }
  { Выводим сообщение о количестве узловых точек: }
  TextOut(20, 20, 'Количество точек: ' + n.ToString)
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

  1. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.
  2. **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 на массив может измениться.
  3. **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;: Возвращает ширину клиентской части графического окна в пикселах
  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** WindowHeight: integer;: Возвращает высоту клиентской части графического окна в пикселах **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Curve(points: **array** **of** Point);: Рисует кривую по точкам, координаты которых заданы в массиве points **procedure** TextOut(x,y: integer; s: string);: Выводит строку s в прямоугольник к координатами левого верхнего угла (x,y) Кривая Curve со случайными координатами в PascalABC.Net

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

uses
  GraphABC;

var
  A: array of point; //Массив точек
  n: byte; //Количество точек кривой

begin
  randomize;
  repeat
    n := random(5, 20); //случайное количество точек от 5 до 20
    SetLength(A, n); //Устанавливаем длину массива
    { Заполняем массив точек А случайными координатами: }
    for var i := 0 to n - 1 do begin
      a[i].X := random(50, WindowWidth - 50); //координата X
      a[i].Y := random(50, WindowHeight - 50) //координата Y
    end;
    SetPenColor(clGreen); //Цвет кривой
    SetPenWidth(3); //Толщина кривой в пикселях
    Curve(A); { <== РИСУЕМ КРИВУЮ по точкам из массива A }
    { Выводим сообщение о количестве узловых точек: }
    SetBrushColor(clPink); //цвет области текста
    TextOut(20, 20, ' Количество точек: ' + n.ToString + ' ');
    { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }
    { ~~~~~~~~~~~~ ПОДПИСЫВАЕМ ТОЧКИ КРИВОЙ ~~~~~~~~~~~~ }
    { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ }
    SetBrushColor(clYellow); //цвет кружечков
    SetPenColor(clBlack); //цвет границы кружечков
    SetPenWidth(1); //толщина границы кружечков
    for var i := 0 to n - 1 do
      Circle(a[i].X, a[i].Y, 4); { <-- рисуем кружечки }
    Sleep(3000); //пауза на 3 секунды
    ClearWindow //очищаем графическое окно белым цветом
  until false { <-- цикл бесконечный }
end.

**unit** GraphABC;: Модуль предоставляет константы, типы, процедуры, функции и классы для рисования в графическом окне **type** Point = System.Drawing.Point;: Тип точки **type** byte;: Представляет 8-битовое целое число без знака.Диапазон значений: 0..255

  1. **procedure** Randomize;: Инициализирует датчик псевдослучайных чисел.2) **procedure** Randomize(seed: integer);: Инициализирует датчик псевдослучайных чисел, используя значение seed. При одном и том же seed генерируются одинаковые псевдослучайные последовательности.
  2. **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 на массив может измениться.
  3. **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;: Возвращает ширину клиентской части графического окна в пикселах
  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** WindowHeight: integer;: Возвращает высоту клиентской части графического окна в пикселах **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clGreen - зеленый **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Curve(points: **array** **of** Point);: Рисует кривую по точкам, координаты которых заданы в массиве points **procedure** SetBrushColor(c: Color);: Устанавливает цвет текущей кисти Цвет: clPink - розовый **procedure** TextOut(x,y: integer; s: string);: Выводит строку s в прямоугольник к координатами левого верхнего угла (x,y) **procedure** SetBrushColor(c: Color);: Устанавливает цвет текущей кисти Цвет: clYellow - жёлтый **procedure** SetPenColor(c: Color);: Устанавливает цвет текущего пера Цвет: clBlack - черный **procedure** SetPenWidth(Width: integer);: Устанавливает ширину текущего пера **procedure** Circle(x,y,r: integer);: Рисует заполненную окружность с центром (x,y) и радиусом r **procedure** Sleep(ms: integer);: Делает паузу на ms миллисекунд **procedure** ClearWindow;: Очищает графическое окно белым цветом **const** false = False;: Представляет логическое значение. Зачем всё это нужно, процедура Curve? Например, если надо нарисовать простенький горизонт, или изобразить воду (которая не бывает идеально прямая), то можно просто обозначить несколько точек, чуть отклюняющихся от прямых, и провести через них кривую Curve – получим иммитацию кривой поверхности. Это мы ещё не раз продемонстрируем на примерах. На этом пока всё, не забывайте комментировать и спрашивать. Если нужно что-либо добавить, добавлю.