Для быстрой выдачи простого сообщения о типе ошибки графи- ческой системы используется функция, преобразующая результат вызова функции GraphResult в сообщение, которое можно вывести на экран процедурой Write.
Эта функция имеет вид:
GraphErrorMsg (ErrorCode: Integer): String;
Возможные графические режимы для различных адаптеров приве- дены в библиотеке модуля Grаph.
Для тестирования графического адаптера в модуле Graph объявле- на процедура:
Эта процедура может быть вызвана до инициализации графики. Че- рез формальные параметры GraphDriver и GraphMode процедура DetectGraph возвращает значения, которые рекомендуется подстав- лять в качестве фактических в процедуру InitGraph.
Номер текущего графического режима для установленного драйве-
ра определяется функцией
GetGraphMode: Integer,
а функция
GetMaxMode: word
возвращает номер максимального режима графического адаптера.
Таким образом, каждый драйвер поддерживает диапазон режимов
0 .. GetMaxMode.
194
Лабораторная работа № 16
Этот же результатможет быть получен из процедуры
GetModeRange (GraphDriver: Integer; Var LoMode, HiMode: Integer),
через параметры LoMode, HiMode возвращающей соответственно нижнюю и верхнюю границы режимов для драйвера GraphDriver.
Функция
GetModeName (GraphMode: Word): String;
возвращает строку, в которой содержится последовательно через пробелы разрешение, имя константы и название палитры для гра- фического режима GraphMode.
Представленный ниже пример поможет определить, в каких графи- ческих режимах может работать используемая ЭВМ.
Uses Graph;
{подключен модуль Graph}
Var
mode: Integer;
{процедура
Procedure GrInit;
<...........>;
инициализации}
Begin
{инициализация}
GrInit;
for mode := 0 to GetMaxMode do
{показ всех режимов}
OutTextXY (10, 10 + mode * 10,
GetModeName (mode));
Readln;
CloseGraph;
End.
Функция
GetDriveName: string
позволяет получить имя используемого драйвера. Ее применение обосновано только в том случае, если в процедуре InitGraph пере- менная GraphDriver определена, как Detect.
Для очистки графического экрана используют процедуры
ClearDevice,
которая очищает графический экран и устанавливает указатель по- зиции в положение (0, 0), и
GraphDefaults,
Процедуры подготовки к работе в графическомрежиме
195
которая, кроме очистки экрана, устанавливает ряд параметров гра- фической системы:
1)графическое окно становится равным размеру экрана;
2)восстанавливается системная цветовая палитра;
3)переназначаются цвета основных линий и фона экрана;
4)толщина и стиль линий принимаются как по умолчанию;
5)цвет и шаблон заливки геометрических фигур и замкнутых ло- маных принимаются как по умолчанию;
6)переустанавливается активный шрифт и его стиль.
Переключение системы в другой графический режим осуществля-
ется процедурой
SetGraphMode (GraphMode: integer),
которая переключает систему в указанный параметром GraphMode графический режим и очищает экран монитора. При этом все до- полнительные характеристики устанавливаются по умолчанию. Пе- реключения возможны только в рамках текущего драйвера.
При написании некоторых программ, использующих и графиче- ские, и текстовые режимы работы ЭВМ, используют процедуру
RestoreCRTMode,
которая возвращает систему в текстовый режим, работавший до инициализации графики. В этом случае возвращение в графический возможно без его инициализации. Обратное переключение осуще-
ствляется при помощи процедуры
GetGraphMode,
которая возвращает номер текущего графического режима. При ра- боте RestoreCRTMode выгрузки графического драйвера не происхо- дит, т.е. он остается в памяти ЭВМ активным. Рассмотрим пример:
{инициализация графики} {диагональ экрана} {вывод первого сообщения} {пауза до нажатия ввода}
{восстановление текстового режима} {вывод второго сообщения} {пауза до нажатия ввода}
{восстановление графического режима} {диагональ экрана} {вывод третьего сообщения} {пауза до нажатия ввода}
Используя процедуру SetGraphMode, следует помнить, что обрат-
ное включение графики устанавливает в исходное состояние все графические параметры модуля Graph и, кроме того, сбрасывает изображение с экрана.
КОНТРОЛЬНЫЕ ЗАДАНИЯ
I. Составить программу инициализации графического режима, предвари- тельно выполнив тестирование графического адаптера. Выполнить построе- ние линии, окружности, эллипса, прямоугольника, многоугольника.
II. Составить программу инициализации графического режима, используя режим автоопределения графического адаптера. Определить: a) тип адаптера, b) номер текущего графического режима, c) номер максимального режима для данного графического адаптера. Вывести на экран информацию: a) о графическом режиме, b) используемом драйвере, c) о разрешающей способ- ности графического режима. Переключиться в текстовый режим, а затем об- ратно включить графический, сопровождая эти действия выводом информа- ции с использованием процедуры write/writeln.
197
Лабораторная работа № 17
РИСОВАНИЕ ГРАФИЧЕСКИХПРИМИТИВОВ И ФИГУР
Система координат. Текущий указатель. Любое изображение на экране образуется как композиция светящихся или погашенных пикселов. Эти точки адресуются двумя координатами X и Y, отсчет которых ведется от верхнего левого угла (для X – слева направо, для Y – сверху вниз).
Координаты верхней левой точки – (0,0). Максимальные адресуе-
мые координаты различных режимов и типов адаптеров дисплеев различны. В модуле Graph предусмотрена возможность программ- ного опроса максимальных координат экрана. Она реализована
функциями
GetMaxX: Integer;
GetMaxY: Integer.
Координаты X и Y могут принимать только целые значения, а зна- чения GetMaxX и GetMaxY должны быть инициализированы сразу после включения соответствующегорежима.
При рисовании графических фигур пользуются понятием “текущий указатель”, который выполняет те же функции, что и курсор в тек- стовом режиме, однако является при этом невидимым.
Положение графического курсора указывает на начальные коорди- наты изображения графического примитива, выводимого от “теку- щей позиции”.
Текущий указатель перемещается специальными процедурами. Процедура MoveTo (X,Y: Integer) перемещает его в точку с коорди- натами X и Y, а процедура MoveRel (dX,dY: Integer) перемещает те- кущий указатель на dX пикселов по горизонтали и соответственно на dY – по вертикали относительно последнего положения текуще- го указателя. Положительные значения dX и dY увеличивают его координаты, а отрицательные – уменьшают.
Для определения текущего положения графического курсора ис-
пользуют функции
GetX: Integer;
198
Лабораторная работа № 17
GetY: Integer,
возвращающие положение указателя соответственно по оси X и по оси Y.
Не все графические процедуры перемещают текущий указатель. Кроме вышеназванных, изменяют его положение лишь процедуры
LineTo, LineRel, OutText.
Все процедуры инициализации и очистки экрана устанавливают его в положение (0,0).
Линии и их стили. Процедура вывода линии (отрезка) на экран (в текущем цвете и стиле) определена в следующем виде
Line (X1,Y1,X2,Y2 : Integer),
где X1,Y1 – координаты начала, а X2,Y2 – конца отрезка. Возможны еще два метода рисования отрезков:
a) из текущей точки в точку с заданными координатами (X,Y) про-
цедурой
LineTo (X,Y : Integer);
b) относительно текущей позиции процедурой
LineRel (dX,dY : Integer),
где dX и dY – приращения координат X и Y относительно точки с текущими координатами. После выполнения текущий указатель пе- реместится в конец отрезка.
В Turbo Pascal можно управлять стилем линий: задавать толщину, тип (сплошные линии, пунктирные и т.п.). Для этого определены следующие типы и константы стилей изображаемых линий:
Type
LineSettingsType = Record
{стиль (тип)}
LineStyle: Word;
Pattern: Word;
{шаблон типа}
Thickness: Word;
{толщина}
End;
{для значений поля LineStyle:}
Const
SolidLn = 0;
{сплошная линия}
DottedLn = 1;
{точечная линия}
CenterLn = 2;
{штрихпунктирная линия}
DashedLn = 3;
{пунктирная линия}
Рисование графических примитивов и фигур
199
UserBitLn = 4;
{тип линии задан явно шаблоном
для значений поля Thickness:}
NormWidth = 1;
{толщина линии в 1 пиксель}
ThickWidth = 3;
{толщина линии в 3 пикселя}
Для получения информации о текущем стиле линий используют процедуру
GetLineSettings (Var LineType: LineSettingsType),
а чтобы установить новый стиль линий, необходимо использовать
Если LineStyle равен UserBitLn, то при определении типа линии сле- дует руководствоватьсяследующими правилами:
a)линия представляет собой совокупность отрезков, длина каж- дого из которых 16 пикселов (если длина отрезка не делится на 16 нацело, последний отрезок обрезается);
b)шаблон–комбинацию задают в виде 16 светящихся или пога- шенных точек (светящейся точке ставится в соответствие 1, пога- шенной – 0).
Поскольку Turbo Pascal не позволяет работать с числами, представ- ленными в двоичной системе счисления, необходимоперевести по-
лученное число в десятичную или шестнадцатеричную системы счисления и поставить его фактическим параметром на место
Pattern. Например, 1100110011001100соответствует 52428 десятич-
ное или $CCCC шестнадцатеричное.
Назначение стиля влияет на действие всех процедур, выводящих на экран отрезки или фигуры, из них состоящие.
Процедуры, выводящие на экран дуги, учитывают только толщину, заданную в стиле.
Коэффициент сжатия изображения. Т.к. отношение высоты эк-
рана к ширине не равно отношению его разрешающей способности по вертикали к разрешающей способности по горизонтали, то для учета этого неравенства вводится специальный показатель – коэф- фициент сжатия изображения (aspect ratio). Его значения могут иметь широкий диапазон. Разрешающая способность адаптеров ко-
200
Лабораторная работа № 17
леблется от 640×200 для CGA до 1024×768 для IBM8514, и отноше-
ние GetMaxX к GetMaxY меняется от 0.3125 (640×200) до 0.75
(1024×768). Таким образом, на единицу длины экрана приходится разное количество пикселов по горизонтали и вертикали. Посколь- ку все операции производятся с пикселaми, то в результате вместо окружности может получиться эллипс, горизонтальная полуось ко- торого равна радиусу, а вертикальная – радиусу, деленному на ко- эффициент сжатия.
В модулеGraph есть две процедуры:
GetAspectRatio (Var A,B: Word),
возвращающая в переменных A и B значения, отношение которых (A/B) и есть коэффициент сжатия изображения, и
SetAspectRatio (A,B: Word),
позволяющая изменить текущий коэффициент сжатия на равный (A/B) и позволяющая писать программы, одинаково работающие на различных ЭВМ.
Окружности, эллипсы, дуги. Для изображения окружностей ис-
пользуется процедура
Circle (X,Y: Integer; Radius: Word),
где (X,Y) – координаты центра окружности, Radius – ее радиус.
В модуле Graph представлены процедура рисования эллипсов, дуг, секторов и процедура, позволяющая рисовать сектор, залитый по данному шаблону. Все они используют параметры StartAngle и EndAngle – начальный и конечный угол дуги. За 0 принято направ- ление оси X (слева направо), и углы отмеряются от оси X против ча- совой стрелки. Все значения этих параметров даются в градусах.
рисование эллиптической дуги с аналогичными параметрами, где XRadius, YRadius – размеры горизонтальной и вертикальной полу- осей соответственно.
Некоторые другие процедуры, изображающие секторы (Sector, PieSlice), а также FillEllipse, выполняют попутно их заливку.
Для определения координат начала и конца дуг окружности или эл-
липса используют процедуру
GetArcCoords (Var ArcCoords: ArcCoordsType).
Тип ArcCoordsType объявлен в модулеGraph следующим образом:
Type
ArcCoordsType = Record
{центр}
X,Y: Integer;
XStart,YStart: Integer;
{начало}
XEnd,YEnd: Integer;
{конец}
End;
Прямоугольники и ломаные. Для построения прямоугольника не-
обходимовызвать процедуру
Rectangle (X1,Y1,X2,Y2: Integer),
которая изобразит на экране прямоугольник с диагональю (X1,Y1) –
(X2,Y2).
Чтобы построить фигуры с большим количеством вершин (в том числе и незамкнутых), можно использовать процедуру
DrawPoly (NumPoints: Word; Var PolyPoints).
Параметр NumPoints – количество точек ломаной, PolyPoints – бес- типовый параметр, состоящий из набора двухкомпонентных запи- сей. Обычно набор точек организуется как массив из записей типа
PointsType:
Type
PointsType = Record
X,Y: Integer; End;
Ниже рассмотрен пример построения графика с помощью данной процедуры.
202
Лабораторная работа № 17
Для построения графиков в декартовой системе координат выберем систему координат таким образом, чтобы ее начало находилось в
точке с координатами (GetMaxX div 2, GetMaxY div 2).
y
GetMaxX div 2
GetMaxY div 2
0
x
GetMaxX, GetMaxY
Рис. 1
Для рисования осей координат OX и OY используем процедуру Line:
Line (0, GetMaxY div 2, GetMaxX, GetMaxY div 2) –
рисует ось X, a
Line (GetMaxX div 2, 0, GetMaxX div 2, GetMaxY) –
рисует ось Y.
После этого необходимопроизвести разметку осей OX и OY . Выбе- рем цену деления в пикселах. Теперь введем коэффициент масшта- бирования MasKoefX, равный числу пикселов, приходящихся на од- но деление.
Отрезок OX будет содержать k подотрезков, по величине равных
MasKoefX,
k = (GetMaxX div 2) div MasKoefX.
Для разметки оси ОX нужно вычислить величину остатка, полу- чающегося при разбиении, т.к. именно с этой позиции следует вес- ти разметку, чтобы она прошла через начало координат.
X = (GetMaxX div 2) mod MasKoefX
Для выполнения разметки воспользуемся циклом While.