Название: Алгоритмы и программы (Афанасьева Т. В.)

Жанр: Информационные системы и технологии

Просмотров: 1348


10.3. модуль graph

 

В персональных компьютерах используется растровый способ генерации изображений. Это означает, что изображение формируется из ряда светящихся точек – пикселей. Каждый пиксель задается парой координат. Для различных  графических  режимов  работы  координатные сетки могут быть разными. Начало координат всегда находится в левом верхнем углу экрана; координата левого верхнего угла (0,0). Состояние каждого пикселя (точнее его цвет) кодируется несколькими байтами, хранящимися в видеопамяти. Специальные программы–драйверы управляют работой адаптера, т. е. определяют, каким образом в процессе формирования изображения будут интерпретироваться данные, распо- ложенные в видеопамяти. Тип драйвера должен обязательно соответст- вовать типу адаптера. Приведем список наиболее распространенных адаптеров.

 

 

Адаптер

Режим

Драйвер

Разрешение

Число цветов

CGA

0–3

CGA

320*200

4

EGA

0

EGALo

640*200

16

EGA

1

EGAHi

640*350

16

 

VGA

0

VGALo

640*200

16

VGA

1

VGAMod

640*350

16

VGA

2

VGAHi

640*480

16

 

Для перехода из текстового режима в графический в программе необходимо использовать процедуру открытия графического режима, INITGRAPH, которая

1) определяет графический адаптер, установленный на компьютере;

2) загружает   и   инициализирует   соответствующий   графический драйвер;

3) переводит адаптер в соответствующий графический режим и

4) возвращает управление вызывающей программе.

Например:

Uses GRAPH; Var Driver,Regim:integer; Begin

Driver:=Vga; Regim:= 1;

 

InitGraph(Driver,Regim,'a:/bgi');

.......... closeGraph;

{или} Driver:=detect; Initgraph(Driver,Regim,'');

...... CloseGraph; End.

 

Процедура СloseGraph

1) завершает работу в графическом режиме;

2) выгружает драйвер из памяти;

3) восстанавливает текстовый режим.

 

При   работе   с   графикой  необходимо  наличие  в   конфигурации системы Turbo Pascal одного или нескольких программ–драйверов (файлов с расширением .BGI), графических шрифтов (файлов с расширением .CHR) и модуля Graph, в котором содержится множество графических функций и процедур. Рассмотрим применение некоторых из них.

В модуле Graph для отображения точки на экране   используется процедура

PutPixel(X,Y:integer;Color:word),

 

где X и Y – экранные координаты точки, Color – ее цвет.

Рассмотрим пример вывода множества точек на экран.

В первых строках после оператора Begin идут операторы инициализации графики и проверка правильности их выполнения. X, Color имеют тип Longint. X берется достаточно большим, а затем постоянно уменьшается, этим и достигается тот эффект, который виден на экране после выполнения программы.

 

uses Crt, Graph;

var

Gd, Gm: Integer;

x, Color:longint;

begin

Gd := Detect;   {автоопределение} InitGraph(Gd, Gm, '');                 {инициализация графики}

if GraphResult <> grOk then     {проверка инициализации графики} Halt(1);         {прекращение выполнения программы}

x:=100000;

repeat   {повторять}

color:=color+3;

PutPixel(Random(x div color), Random(x div color), Color div 13); until KeyPressed;   {до нажатия клавиши} settextstyle(3,0,4);        {установка параметров текста} outtextxy(250,400,'press enter'); {вывод текста}

setcolor(14);     {установка желтого цвета } outtextxy(200,290,'Procedure PutPixel');           {вывод текста} READLN;

CloseGraph;     {прекращение работы в графическом режиме}

end.

 

Для изображения окружностей используется процедура

 

Circle(x,y:INTEGER;radius:WORD);

 

Здесь (X,Y) – координаты центра окружности, Radius – ее радиус.

Пример построения окружности со случайными координатами и радиусом.

uses Graph,crt;

var

Gd, Gm: Integer;

x,y:integer;

Radius: Integer;

begin

Gd := Detect;   {автоматическая выборка режима} InitGraph(Gd, Gm, ''); {инициализация графики}

if GraphResult <> grOk then  {проверка инициализации,если}

{ ошибка то}

Halt(1);                {прекращение выполнения программы}

repeat x:=x+1; y:=y+1;

Radius:=Radius+1;

setcolor(random(15));   {задание случайного цвета} Circle(random(x*7),random(y*5), Radius) ;     {рисует окруж}

{ности со слу–} until keypressed;                               {чайными координатами} settextstyle(3,0,4);                     {установка параметров текста} outtextxy(250,400,'press enter');     {вывод текста} setcolor(14);  {установка желтого цвета } outtextxy(200,290,'Procedure Circle');         {          вывод текста} readln;

CloseGraph;

end.

Для построения эллиптических дуг предназначена процедура

Ellipse (X, Y: integer; StAngle, EndAngle: word; XR, YR: word),

где (X, Y) – центр эллипса в дисплейных координатах, XR и YR – горизонтальная  и вертикальная оси. Дуга эллипса вычерчивается текущим цветом от начального угла StAngle до конечного угла EndAngle. Значения StAngle=0 и EndAngle=359 приведут к вычерчиванию полного эллипса.  В следующем  примере процедура Ellipse(100,  100, 0,  360,  30,  50) строит полный эллипс,   а процедура Ellipse(100, 100, 0, 460, 30, 100) примерно половину.

Пример построения эллипсов

Program Mih;

uses Graph,Crt;

var Gd, Gm,x,y: Integer;

begin

Gd := Detect;   {автоматическая выборка режима} InitGraph(Gd, Gm, '');              {инициализация графики}

if GraphResult <> grOk then     {проверка на ошибку инициализации} Halt(1);     {прекращение выполнения программы}

x:=1; y:=1; repeat

setcolor(random(16));   {выбор случайного цвета} Ellipse(x, y, 0, 360, 30, 50);

x:=x+1;

y:=y+1;

until y>=480;                {до тех пор пока у не выйдет за границу экрана}

settextstyle(3,0,4);                    {установка параметров текста} outtextxy(400,200,'press enter');     {вывод текста} setcolor(14);     {установка желтого цвета } outtextxy(350,100,'Procedure ELLIPSE');        {вывод текста} readln;

CloseGraph;     {выход из графического режима}

end.

 

Процедура  вывода  отрезка  прямой  на  экран  (в  текущем  цвете  и стиле) определена следующим образом:

Line(x1,y1,x2,y2:integer).

 

В ней задаются координаты начальной (x1, y1) и конечной точек (x2, y2) линии. Применяется только в графическом режиме. Рассмотрим программу построения линий.

В первых строках, после оператора Begin идут операторы инициализации графики и проверка правильности их выполнения. Процедура l(d,c:byte) собственно и производит построение получаемой картины на экране. Процедура начинается тем, что устанавливаются координаты x1, y1, x2, y2 линии.   Координаты соответствуют правому и левому нижним углам. Затем координата левого угла (по y) начинает уменьшаться, каждый раз на d пикселов (текущий цвет – с). Примерно то же  самое для остальных углов. В результате вызова процедуры в главной программе  экран  заполняется  множеством  линий,  причем  различного цвета и на разные промежутки.

Пример построения линий

uses graph,crt;

procedure l(d,c:byte);

var       x1,y1,x2,y2:integer;

begin x1:=639; y1:=479; x2:=1; y2:=479; repeat setcolor(c); y2:=y2–d;

line(x1,y1,x2,y2);

until y2<=1; x1:=1; y1:=1; x2:=639; y2:=479; repeat setcolor(c);

line(x1,y1,x2,y2);

y2:=y2–d; until y2<=1; x1:=639; y1:=1;

x2:=1; y2:=479; repeat

setcolor(c);{ задание цвета линий }

line(x1,y1,x2,y2);

y2:=y2–d; until y2<=1; x1:=1; y1:=479; x2:=639; y2:=1;

repeat

setcolor(c);{ задание цвета линий }

line(x1,y1,x2,y2);

x2:=x2–d;

until x2<=1;

end;{l}

 

{***********************MAIN*********}

var driver,mode:integer; begin

driver:=vga;      {драйвер} mode:=vgahi;           {режим графики} initgraph(driver,mode,'');  {инициализация графики}

if graphresult<>0 then   {проверка на ошибку инициализации

графики }

 

 

halt(1); {прекращение выполнения программы}

l(8,2);

l(15,14);

setcolor(11);     {установка желтого цвета } settextstyle(3,0,4);          {установка параметров текста} outtextxy(250,400,'press enter');           {вывод текста} outtextxy(200,290,'Procedure Line'); {вывод текста} readln;                        {ждет нажатия ввода}

closegraph;       {выход из графического режима}

end.

Для      построения    отрезков         применяются еще      две      процедуры

(кроме line):

LineTo и LineRel.

Процедура LineTo(x,y) строит отрезок из точки текущего положения указателя до точки с координатами (x,y). Процедура LineRel(dx,dy) проводит отрезок от точки текущего положения указателя до точки (cpx + dx,cpy + dy), где cpx и cpy – текущие координаты cp.

В данном примере экран заполняется множеством отрезков различных цветов, при этом получается интересный визуальный эффект (GetmaxX, GetmaxY – определение значений максимальных координат экрана).

 

Пример построения линий (LineTo,LineRel)

program wind; uses Crt, Graph; var

Gd, Gm: Integer;

begin

Gd := Detect;   {автоопределение} InitGraph(Gd, Gm, '');                 {инициализация графики}

if GraphResult <> grOk then {проверка ошибки инициализации графики}

Halt(1);            {прекращение выполнения программы}

Randomize;      {при каждом запуске получается новая картина}

repeat

setcolor(random(15));               {случайный выбор цвета} delay(100);         {задержка на 100 мс.} lineto(random(getmaxx),random(getmaxy)); linerel(50,–50);

until KeyPressed;            {пока не нажата клавиша} settextstyle(3,0,4);        {установка параметров текста} outtextxy(250,400,'press enter');           {вывод текста} setcolor(14);  {установка желтого цвета }

outtextxy(150,290,'Procedures LineTo and LineRel'); {вывод текста}

readln;

CloseGraph;     {выход из графики}

end.

 

Для      построения    прямоугольников      используется  процедура построения прямоугольника на плоскости:

 

Rectangle(x1,y1,x2,y2:integer),

 

где  x1,  y1  –  координаты  левого  верхнего  угла,  x2,  y2  –  координаты правого нижнего угла прямоугольника. Это очень полезная процедура, с ее помощью, в частности, можно легко построить диаграмму для визуального анализа данных.

 

Пример построения прямоугольников

Program Mih6;

uses graph,crt;

var x1,y1,x2,y2,d,j,k:integer; Gd, Gm: Integer;

begin

Gd := Detect;   {автоопределение}

InitGraph(Gd, Gm, '');   {установка графического режима}

if GraphResult <> grOk then     {проверка инициализации графики} Halt(1);         {прекращение выполнения прграммы}

cleardevice;      {очистка окна}

x1:=640; y1:=480; x2:=1; y2:=1; repeat

setcolor(yellow);           {установка цвета}

rectangle(x1,y1,x2,y2);

x1:=x1–2; y1:=y1–2; x2:=x2+2; y2:=y2+2; until x1<=1; setcolor(1);

settextstyle(3,0,4);        {установка параметров текста} outtextxy(250,400,'press enter');     {вывод текста} outtextxy(200,290,'Procedure Rectangle' ); {вывод текста} READLN;

closegraph;{выход из графики}

end.

В модуле Graph имеется множество средств построения различных геометрических  фигур,  которые  позволяют  сделать  выводимое изображение   более красочным и эффективным. Среди таких средств прежде всего следует отметить «заливку» замкнутых областей экрана с помощью различных узоров. В модуль Graph включен ряд стандартных шаблонов различных узоров для заполнения внутренних и внешних областей различных геометрических фигур. Узор может быть окрашен в допустимые для установленной палитры цвета. Комбинацию узор–цвет принято   называть стилем заполнения. Для работы со стандартными стилями используются рассматриваемые ниже функции GetFillSettings и SetFillStyle.

 

SetFillStyle (Pattern: WORD; Color: WORD)

устанавливает маску Pattern и ее цвет Color, т. е. определяет стиль заполнения.

 

Процедура

 

GetFillSettings(VAR FillType: FillSettingsType)

 

возвращает в переменной FillType,   которая имеет тип, объявленный в модуле Graph следующим образом:

 

TYPE

FillSettingsType = RECORD

Pattern: WORD; {шаблон} Color: WORD; {цвет} END;

номер шаблона заполнения (Pattern) и его цвет (Color).

 

Осталось рассмотреть последнюю процедуру этого семейства – FloodFill.  Она служит для заполнения заданным с помощью SetFillStyle и SetFillPattern стилем области, расположенной либо внутри замкнутого контура, либо вне его. Для ее задания используется следующий синтаксис:

FloodFill (X, Y: INTEGER; Border: WORD),

где  X,  Y  –  координаты  точки  внутри  или  вне  замкнутого  контура. Параметр Border задает цвет контура. В зависимости от расположения указанной точки по отношению к контуру будет производиться заполнение текущим узором либо области, ограниченной контуром, либо части экрана, расположенной вне границ контура. Если указанный контур не является замкнутым (отметим, что контуры, включающие в себя часть границы экрана, относятся к замкнутым), то будет заполнен весь экран. Использование  шаблонов   с   достаточно      редким   заполнением      для

небольших      по размеру областей может привести к некорректной работе процедуры.

 

Процедра

SetTextStyle(Font:word;direction:Word;Charsize:Word)           устанавливает текущие тип шрифта, направление текста и размер символов.

Font – тип шрифта;

Direction – направление текста; CharSize – размер символов.

 

В случае аварийной ситуации процедура устанавливает код ошибки :

-8 – не найден файл со шрифтом;

-9 – нет памяти для загрузки шрифта;

-11 – ошибка графической системы;

-12 – ошибка ввода–вывода графической системы;

-13 – ошибка в файле со шрифтом;

-14 – неверный номер шрифта.

 

Процедура      OutText(TextString:String)        выводит         на        экран   строку текста, начиная с текущего положения курсора.

 

Пример построения закрашенных областей на экране

uses graph,crt;

var

p:fillpatterntype;{маска заполнения}

driver,mode,i:integer;

begin

driver:=vga;      {драйвер} mode:=vgahi;                     {режим графики} Initgraph(driver,mode,'');                            {инициализация графики}

if graphresult<>0 then   {проверка инициализации графики}

halt(1); {прекращение выполнения программы}

for i:=1 to 8 do begin

p[1]:=7; {             в результате              } p[2]:=221;{          выполнения                } p[3]:=7; {                                                 } p[4]:=10; {       этих операторов на         } p[5]:=114;{                экране                    } p[6]:=80; {                появится                 } p[7]:=114;{       множество        } p[8]:=130;{              кружочков               } end;

line(10,10,630,10) ;      {вычерчивет границы рамки }

line(10,10,10,470);       {вычерчивет границы рамки } line(10,470,630,470);                      {вычерчивет границы рамки } line(30,30,610,30);    {вычерчивет границы рамки } line(30,460,610,460);                      {вычерчивет границы рамки } line(30,460,610,460);                     {вычерчивет границы рамки } line(30,30,30,460);            {вычерчивет границы рамки } line(610,30,610,460);                      {вычерчивет границы рамки } setfillstyle(9,7);

floodfill(20,25,15);

setlinestyle(0,0,1);

rectangle(45,45,595,445);        {построение прямоугольника}

setfillstyle(1,8); {задает стандартный орнамент и цвет заполнения фигур}

floodfill(85,34,15);        {Закрашивает область,ограниченную непрерывной линией,}

setfillpattern(p,15);        {текущим орнаментом и цветом заполнения}

bar(45,45,595,445);                   {построение прямоугольника} setcolor(12);          {установка цвета} settextstyle(1,0,12);                  {установка шрифта} outtextxy(55,170,'Pmd–11');     {вывод текста}

settextstyle(3,0,4);                    {установка параметров текста} outtextxy(250,400,'press enter');     {вывод текста} setcolor(14);     {установка желтого цвета }

outtextxy(150,435,'Procedure SetFillPattern');  {вывод текста} READLN;

end.

Пример вывода текста на экран

 

{Процедура SetTextStyle}

uses graph,crt,font;

var

driver,mode:integer;

c,g,r:byte; k:char; s:string;

begin

driver:=vga;      {драйвер} mode:=vgahi;                     {режим графики} initgraph(driver,mode,'');                            {инициализация графики}

if graphresult<>0 then   {проверка инициализации графики}

halt(1); {прекращение выполнения программы}

settextstyle(4,0,2);

setcolor(14);     {задание цвета}

outtextxy(100,200,'Введите номер шрифта (от 1 до 7)'); READLN(g);

cleardevice;      {очистка окна} outtextxy(100,200,'Введите номер цвета (от 0 до 15)'); READLN(c);

cleardevice;

outtextxy(30,200,'Введите текст (желательно латинскими буквами)');

READLN(s);

cleardevice;

outtextxy(90,200,'Введите размер текста (от 1 до 10 ) '); READLN(r);

cleardevice;

outtextxy(10,200,'Вывод вертикальный(Y) или горизонтальный (N) ?' );

setcolor(9);

outtextxy(100,300,'      Нажмите на Y или на N');

k:= READkey; {запоминает введенный с клавиатуры символ}

if k = 'y'then settextstyle(g,1,r)   {вертикальный вывод}

else settextstyle(g,0,r);  {горизонтальный вывод}

cleardevice;      {очистка окна}

moveto(100,100);        {перемещение курсора в точку с координатами 100,100}

setcolor(c);       {задание цвета}

outtext(s);

settextstyle(3,0,4);                    {установка параметров текста} outtextxy(250,400,'press enter');     {вывод текста} setcolor(14);     {установка желтого цвета }

outtextxy(200,290,'Procedure SetTextStyle');   {вывод текста} READLN;

closegraph;       {прекращение работы в графическом режиме}

end.

Контрольные вопросы

1. Что понимают под модулем?

2. Из каких частей состоит модуль?

3. Когда возникает необходимость использовать модули?

4. Типы модулей.

5. Назовите стандартные модули Turbo Pascal и опишите их назначение.

6. Правила использования модулей в программах.

7. Какой объем памяти отводится под программу, а какой – под модуль?

8. Какое расширение имеет имя файла модуля?