Методическое пособие 555
.pdfПродолжение табл. 7.2
PenWidth: Integer |
Возвращает |
ширину |
текущего |
|||
пера |
|
|
|
|
||
|
|
|
|
|
||
SetPenStyle(style: |
Устанавливает |
стиль |
текущего |
|||
DashStyle) |
пера |
|
|
|
|
|
PenX: Integer |
Возвращает |
x-координату |
те- |
|||
кущей позиции рисования |
|
|||||
|
|
|||||
PenY: Integer |
Возвращает |
y-координату |
те- |
|||
кущей позиции рисования |
|
|||||
|
|
|||||
SetBrushColor(c: |
Устанавливает |
цвет |
текущей |
|||
Color) |
кисти |
|
|
|
|
|
BrushColor: Color |
Возвращает цвет текущей кисти |
|||||
SetBrushStyle(bs: |
Устанавливает |
стиль |
текущей |
|||
BrushStyleType) |
кисти |
|
|
|
|
|
SetBrushHatch(bh: |
Устанавливает |
штриховку |
те- |
|||
HatchStyle) |
кущей кисти |
|
|
|
|
|
SetFontSize(size: |
Устанавливает размер текущего |
|||||
Integer) |
шрифта в пунктах |
|
|
|||
FontSize: Integer |
Возвращает |
размер |
текущего |
|||
шрифта в пунктах |
|
|
||||
|
|
|
||||
SetFontName(name: |
Устанавливает |
имя |
текущего |
|||
String) |
шрифта |
|
|
|
|
|
SetFontColor |
Устанавливает |
цвет |
текущего |
|||
шрифта |
|
|
|
|
||
|
|
|
|
|
||
SetFontStyle(fs: |
Устанавливает |
стиль |
текущего |
|||
Integer) |
шрифта |
|
|
|
|
|
TextWidth(s: String): |
Возвращает ширину строки s в |
|||||
пикселях при текущих настрой- |
||||||
Integer |
ках шрифта |
|
|
|
|
|
|
|
|
|
|
||
TextHeight(s: |
Возвращает высоту строки s в |
|||||
пикселях при текущих настрой- |
||||||
String): Integer |
||||||
ках шрифта |
|
|
|
|
||
|
|
|
|
|
121
Стили пера задаются перечислимым типом DashStyle. Для стилей пера определены следующие константы: psSolid (сплошное перо), psClear (прозрачное перо), psDash (штриховое перо), psDor (пунктирное перо), psDashDot (штрихпунктирное перо), psDashDotDot (альтернативное штрихпунктирное перо).
Для стилей кисти можно использовать следующие константы: bsSolid (сплошная кисть), bsClear (прозрачная кисть), bsHatch (штриховая кисть), bsGradient (градиентная кисть). Константы стилей штриховки представлены в справочной системе PascalABC.
Стиль шрифта задается одной из следующих констант: fsNormal (обычный), fsBold (жирный), fsItalic (на-
клонный), fsBoldItalic (жирный наклонный), fsUnderline (подчеркнутый), fsBoldUnderline (жир-
ный подчеркнутый), fsItalicUnderline (наклонный подчеркнутый), fsBoldItalicUnderline (жирный наклонный подчеркнутый).
1.4. Графические примитивы
Некоторые из процедур, предназначенных для рисования графических примитивов представлены в таблице 7.3 (полный список – в справочной системе PascalABC.Net).
|
Таблица 7.3 |
|
Графические примитивы |
||
Имя процедуры (функции) |
Действие |
|
PutPixel(x,y: Integer; |
Закрашивает пиксел с координа- |
|
c: Color) |
тами (x, y) цветом c |
|
|
|
|
GetPixel(x,y: Integer): |
Возвращает цвет пиксела с коор- |
|
Color |
динатами (x, y) |
|
MoveTo(x,y: Integer) |
Устанавливает текущую позицию |
|
рисования в точку (x, y) |
||
|
||
|
Рисует отрезок от текущей пози- |
|
LineTo(x,y: Integer) |
ции до точки (x, y). Текущая по- |
|
|
зиция переносится в точку (x, y) |
122
Продолжение табл. 7.3
Line(x1,y1,x2,y2: |
Рисует отрезок от точки (x1, |
|||||||
Integer) |
y1) до точки (x2, y2) |
|
||||||
DrawCircle(x,y,r: |
Рисует |
окружность |
с |
центром |
||||
Integer) |
(x, y)и радиусом r |
|
|
|||||
Circle(x,y,r: Integer); |
Рисует |
заполненную |
окруж- |
|||||
ность с центром (x, y) и радиу- |
||||||||
|
сом r |
|
|
|
|
|
||
|
Рисует границу эллипса, огра- |
|||||||
DrawEllipse |
ниченного |
прямоугольником, |
||||||
заданным координатами проти- |
||||||||
(x1,y1,x2,y2: Integer) |
||||||||
воположных вершин (x1, y1) и |
||||||||
|
||||||||
|
(x2, y2) |
|
|
|
|
|||
|
Рисует |
заполненный |
эллипс, |
|||||
Ellipse(x1,y1,x2,y2: |
ограниченный |
прямоугольни- |
||||||
ком, |
заданным |
координатами |
||||||
Integer) |
||||||||
противоположных вершин (x1, |
||||||||
|
||||||||
|
y1) и (x2, y2) |
|
|
|
||||
|
Рисует |
границу прямоугольни- |
||||||
DrawRectangle |
ка, |
заданного |
координатами |
|||||
(x1,y1,x2,y2: Integer) |
противоположных вершин (x1, |
|||||||
|
y1) и (x2, y2) |
|
|
|
||||
|
Рисует |
заполненный |
прямо- |
|||||
Rectangle(x1,y1,x2,y2: |
угольник, заданный координа- |
|||||||
Integer) |
тами противоположных вершин |
|||||||
|
(x1, y1) и (x2, y2) |
|
|
|||||
|
Рисует |
заполненный |
много- |
|||||
|
угольник, |
координаты |
вершин |
|||||
Polygon(points: array |
которого |
заданы |
в |
массиве |
||||
points типа Point (данные |
||||||||
of Point) |
||||||||
типа Point представляют со- |
||||||||
|
||||||||
|
бой пару целых чисел x и y, за- |
|||||||
|
дающих точку на плоскости) |
123
Окончание табл. 7.3
Polyline(points: array |
Рисует ломаную по точкам, ко- |
|||
ординаты |
которых заданы |
в |
||
of Point) |
||||
массиве points |
|
|||
|
|
|||
TextOut(x,y: integer; |
Выводит строку s в прямо- |
|||
угольник с координатами лево- |
||||
s: string) |
||||
го верхнего угла (x,y) |
|
|||
|
|
|||
TextOut(x,y: integer; |
Выводит |
вещественное r |
в |
|
прямоугольник с координатами |
||||
r: real) |
||||
левого верхнего угла (x, y) |
|
|||
|
|
2. Практическая часть
Задание 1. Изучите возможности, которые предоставляет модуль GraphABC, воспользовавшись справочной системой (Справка -> Стандартные модули –> модуль GraphABC). Особое внимание уделите следующим разделам:
–типы и переменные;
–графические примитивы;
–функции для работы с цветом;
–цветовые константы;
–подпрограммы для работы с пером;
–стиль пера;
–подпрограммы для работы с кистью;
–стили кисти;
–подпрограммы для работы со шрифтом;
–подпрограммы для работы с графическим окном.
Задание 2. Введите в редактор кода и выполните приведенные ниже программы.
program p_7_2a; uses
graphABC; begin
124
ClearWindow(clYellow);
//очищаем графическое окно желтым цветом
//Задаем цвет пера, толщину пера и цвет кисти
SetPenColor(clGreen); SetPenWidth(5); SetBrushColor(clBlue);
//Рисуем круг радиусом 150 пикселей в центре окна
Circle(WindowWidth div 2, WindowHeight div 2, 150);
//Закрашиваем пиксель в центре окна //красным цветом
PutPixel(WindowWidth div 2, WindowHeight div 2, clRed);
end.
//Рисует пятиугольник, в центре экрана выводит
//строку "Hellow!" program p_7_2b; uses
graphABC;
var
poly: array of Point;
begin
//poly - это динамический массив, нужно задать //его длину(выделить память) следующей //процедурой:
SetLength(poly,5);
//В массив Poly записываем координаты вершин //многоугольника (минимальное значение индекса //динамического массива - 0)
poly[0].X:=20; poly[0].Y:=20; poly[1].X:=160; poly[1].Y:=130; poly[2].X:=160; poly[2].Y:=160; poly[3].X:=40; poly[3].Y:=180; poly[4].X:=20; poly[4].Y:=20;
//Рисуем многоугольник, координаты вершин // которого задаются массивом poly
125
Polygon(poly);
//Рисуем приветствие
TextOut(WindowWidth div 2, WindowHeight div 2, 'Hellow!');
end.
Задание 3. Модифицируйте вторую программу таким образом, чтобы был построен такой же многоугольник, но с использованием процедур MoveTo и LineTo вместо
Polygon.
Задание 4. Напишите программу для рисования изображения, показанного на рис. 7.1.
Рис. 7.1
Задание 5. Напишите программу для рисования фрактала Кантора.
Решение. Рассмотрим горизонтальный отрезок AB длиной L (рис. 7.2). Выбросим из этого отрезка интервал (L/3, 2L/3) (отрезок CD). Затем из каждого оставшегося отрезка также выбрасываем средние трети и т.д. После n таких итераций получим 2n отрезков длиной 3-nL. В пределе n получим фрактал Кантора.
126
Рис. 7.2
Поскольку алгоритм построения фрактала Кантора носит рекурсивный характер, удобно воспользоваться рекурсивной процедурой (назовем её Kantor). Входными параметрами процедуры будут вещественные переменные xA и xB – координаты концов отрезка и целочисленная переменная iter – номер текущей итерации:
procedure Kantor(xA, xB: Real; iter: Integer);
Процедура должна вычислить координаты xС и xD точек C и D и нарисовать два горизонтальных отрезка AС и DB (отступив на заданное расстояние вниз от отрезков, нарисованных на предыдущей итерации). После этого процедура должна дважды вызвать сама себя уже с другими параметрами: номер итерации должен быть увеличен на единицу, а координаты концов отрезка должны соответствовать двум новым отрезкам – AС и DB:
Kantor(xA, xC, iter + 1);
Kantor(xD, xB, iter + 1);
Рекурсивные вызовы должны прекратиться, когда переменная iter окажется равной некоторому значению
MAX_ITER.
Полный текст программы представлен ниже.
program Kantor_fractal;
127
uses GraphABC; const
L = 600; //длина исходного отрезка h = 40; //смещение по вертикали
MAX_ITER = 4; //число итераций
procedure Kantor(xA, xB: Real; iter: Integer); var
xC,xD: Real; begin
//Вычисляем координаты точек C и D xC := (2*xA + xB)/3;
xD := (xA + 2*xB)/3;
//Рисуем отрезки
Line(round(xA), h+iter*h, round(xC), h+iter*h); Line(round(xD), h+iter*h, round(xB), h+iter*h);
//Рекурсивные вызовы процедуры Kantor //для двух новых отрезков:
if (iter <= MAX_ITER) then begin Kantor(xA, xC, iter + 1); Kantor(xD, xB, iter + 1);
end; end;
begin
//Рисуем начальный отрезок
Line(10, h, 10 + L, h);
//Вызов процедуры Kantor Kantor(10, 10+L, 1);
end.
Задание 6. Модифицируйте программу из предыдущего задания таким образом, чтобы получить изображение «гребня Кантора» (рис. 7.3).
128
Рис. 7.3
Задание 7. Написать программу, рисующую график функции f(x) = 1+x2sinx в диапазоне значений x, задаваемом пользователем.
Решение. Для рисования графика функции определим положение начала координат на экране (координаты соответствующего пикселя обозначим через x0 и y0), а также размеры и положение прямоугольной области вывода графика путем задания координат ее верхнего левого (xLeft, yLeft) и правого нижнего (xRight, yRight) углов (см. рис. 7.4).
Рис. 7.4
Чтобы изображение выглядело аккуратно, область вывода графика разместим таким образом, чтобы от каждого края графического окна имелся отступ величиной 40 пикселей:
xLeft := 40; yLeft := 40;
129
xRight := WindowWidth - 40;
yRight := WindowHeight - 40;
Пусть мы строим график в интервале [xmin, xmax], а fmin и fmax - минимальное и максимальное значение функции на этом интервале (значения xmin и xmax по условию задачи вводит пользователь, а значения fmin и fmax необходимо определить путем непосредственных вычислений).
Выберем следующий способ изображения линии графика: будем перебирать значения аргумента x с некоторым мелким шагом step и вычислять значения функции y = f(x), после чего определять соответствующие координаты пикселя на экране и подсвечивать его процедурой PutPixel.
Возникает вопрос, как определить координаты пикселя, который необходимо закрашивать для изображения точки (x, f(x))? Очевидно, для этого следует осуществлять масштабирование таким образом, чтобы значению x = xmax соответствовала правая граница области вывода графика xRigth, а значению x = xmin – левая граница xLeft. Аналогиченое соответствие должно быть между значениями функции f = fmax и f = fmin и верхней и нижней границами области вывода графика yLeft и yRight. С этой целью значения x и f(x) необходимо умножать на следующие коэффициенты:
scaleX := (xRight - xLeft)/(xmax - xmin); scaleY := (yRight - yLeft)/(fmax - fmin);
К полученным таким образом координатам пикселя в графическом окне необходимо добавлять координаты пикселя (x0, y0), соответствующие началу координат. Чтобы график полностью помещался в заданной области вывода, начало координат в графическом окне должно быть задано так (см. рис.
7.4):
x0 := xLeft - round(xmin*scaleX);
y0 := yLeft + round(fmax*scaleY);
130