Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОП Конспект лекций - Паскаль.doc
Скачиваний:
20
Добавлен:
30.11.2018
Размер:
1.46 Mб
Скачать

Тема 31: Графічні можливості tp 7.0. Використання бібліотеки Graph

Для одержання доступу до графічних процедур і функцій потрібно в розділі Uses підключити модуль Graph. Часто в роботі з графікою необхідні засоби модуля Crt, тому підключаємо і його:

uses crt, graph;

Файли типу .bgi дозволяють настроїтися на конкретний графічний адаптер: CGA, EGA, VGA.

Для ініціалізації графіки і переходу в графічний режим використовується процедура

InitGraph(var GraphDriver : integer; var GraphMode : integer; Path : string);

де змінна GraphDriver задає тип драйвера, що підключається, наприклад:

GraphDriver := EGA; (можна задати цифрою 3)

Приведемо найбільш розповсюджені драйвери (табл. 31.1).

Таблиця 31.1. Драйвери

Драйвер

Режим

Розмір

Файл

CGA (1)

CGACO, CGAHi

320x200 (640x200)

cga.bgi

EGA (3)

EGALo, EGAHi

640x200 (640x350)

egavga.bgi

VGA (9)

VGALo, VGAHi

640x200 (640x350)

egavga.bgi

Змінна GraphMode задає режим графіки, наприклад:

GraphMode := EGAHi;

у параметрі Path указується шлях до каталогу в якому містяться bgi-файл. У нас на комп'ютерах ці файли розташовані в каталозі

С:\ТР\BGI;

Для автовизначення графічного режиму потрібно змінній GraphDrive привласнити значення константи Detect, наприклад:

GraphDriver:=Detect;

Приклад.

uses Graph;

var Gm, Gd : integer; {драйвер і режим}

begin

Gd := Detect; {режим автовизначення}

InitGraph(Gd, Gm, 'c:\tp\bgi'); {ініціалізація графіки}

Для визначення помилок при ініціалізації графіки використовується функція GraphResult. Якщо після ініціалізації графіки її значення дорівнює 0, то помилок немає, інакше - є. Для видачі повідомлення про тип помилки використовується функція GraphErrorMsg, що перетворює результат функції GraphResult у повідомлення, виведене на екран процедурою Write. Функція має вигляд:

GraphErrorMsg(ErrorCode);

Приклад видачі повідомлення про помилки.

uses Graph;

var Gm, Gd : integer;

ErrorCode : integer; {зберігає номер помилки}

begin

Gd := Detect;

InitGraph(Gd,Gm,'c:\tp\bgi');

ErrorCode := GraphResult; {збереження результ. ініціал.}

if ErrorCode <> 0 then begin

writeln('Помилка графіки: ',GraphErrorMsg(ErrorCode));

Halt(1);

end;

. . .

Процедура CloseGraph застосовується, коли графічна програма завершує свою роботу чи коли потрібно вийти з графічного режиму в текстовий.

Виведення тексту в графічному режимі.

Зображення звичайно супроводжують різними поясненнями. Для виведення тексту використовують процедуру OutTextXY(x,y,text), де х, у - координати точки початку виведення тексту, text - константа чи змінна типу string. Процедура OutText(text) виводить текст, починаючи з поточного положення покажчика.

Для визначення типу шрифту, його напрямку і розміру, використовується процедура

SetTextStyle(font, direction, charsize);

де константа font задає шрифт і вибирається з таблиці 31.2.

Таблиця 31.2. Список констант для визначення шрифту.

Ім'я константи

Номер

Шрифт і файл, де він зберігається

DefaultFont

0

Матричний 8х8 (Graph.tru)

TriplexFont

1

Напівжирний (trip.chr)

SmallFont

2

Тонкий (ntt.chr)

SansSerifFont

3

Рубаний (sans.chr)

GothicFont

4

Готичний (goth.chr)

За замовчуванням задається шрифт №0.

Константа direction задає напрямок виводимих символів:

0 - горизонтальне;

1 - вертикальне (знизу нагору),

константа charsize задає розмір символів від 1 до 10.

Приклад. Демонстрація шрифтів.

uses Graph, Crt;

var

gd, gm : integer; i : word;

begin

gd := Detect;

InitGraph(gd, gm, ‘c:\tp\bgi’);

if GraphResult<>0 then Halt(1);

SetColor(2);

SetTextStyle(0,0,2);

OutTextXY(75, 10, ‘П Р И К Л А Д И Ш Р И Ф Т І В’);

SetColor(3); SetTextStyle(0,0,1);

OutTextXY(120,140, ‘DefaultFont. Матричний шрифт 8х8 (за ‘, ‘замовченням)’);

SetColor(4); SetTextStyle(1,0,1);

OutTextXY(160,70,’TriplexFont(SetTextStyle(1,0,1))’);

SetColor(5); SetTextStyle(2,0,5);

OutTextXY(160,110, ‘SmallFont (SetTextStyle(2,0,5))’);

SetColor(6); SetTextStyle(3,0,1);

OutTextXY(160,130, ‘SansSerifFont(SetTextStyle(3,0,1))’);

SetColor(7); SetTextStyle(4,0,4);

OutTextXY(80,170, ‘GothicFont (SetTextStyle(4,0,4))’);

SetColor(15); SetTextStyle(0,1,1);

OutTextXY(300,250, 'Вертикальне виведення');

ReadKey:

CloseGraph;

end.

Для виведення числа потрібно його перетворити процедурою Str у рядок, а потім операцією “+” підключити його до рядку, що виводиться OutTextXY.

Наприклад:

. . .

max := 2.14;

str(max : 4:2,smax); {результат перетворення в smax}

OutTextXY(400,40 ‘Максимум = ‘+smax);

. . .

Можливості Graph

У графічному режимі є невидимий поточний покажчик СР (current pointer), що виконує ті ж функції, що і курсор у текстовому режимі. Система координат починається з верхнього лівого кута (координати 0,0). Значення Х збільшується зліва направо, а Y - зверху вниз. Екран представляється у вигляді прямокутного масиву адресуємих точок. Кількість точок по горизонталі і вертикалі різне для різних адаптерів. Максимальне значення координат можна визначити функціями

GetMax:integer і GetMax:integer.

Процедура ClearDevice очищає екран і поміщає СР у точку (0,0).

Для переміщення СР використовуються процедури:

MoveTo(x,y:integer) - переміщає поточний СР у точку X,Y;

MoveRel(dx,dy:integer) - переміщає СР на dX і dY точок щодо поточного СР.

Функції GetX:integer і GetY:integer дають поточне положення СР.

Процедура PutPixel(x,y,color) виводить крапку в X,Y кольором color.

Функція GetPixel(x,y) повертає номер кольору пикселя в X,Y.

Процедура Line(x1,y1,x2,y2:integer) виводить лінію (X1,Y1 - початок лінії, x2,y2 - кінець лінії; РС у точці x2,y2).

Процедура LineTo(x,y) з'єднує крапку РС із крапкою X,Y і РС переходить у X,Y.

Процедура LineRel(dx,dy) зміщає РС у крапку X+dX, Y+dY і малює лінію (x,y,x+dx,y+dy).

Можна змінювати стиль зображуваних ліній використовуючи процедуру:

SetLineStyle(вид, зразок, товщина);

де параметр “вид” дозволяє задати лінію або 4-х стандартних типів, або за своїм зразком.

0 - безперервна лінія;

1 - крапкова;

2 - штрих-пунктирна;

3 - штрихова;

4 - дозволяє задати вид лини користувача. Для цього призначений параметр “зразок”:word, 2 байти якого задають тип лінії; параметр “товщина” задає товщину лінії в пикселях (1 - нормальна товщина, 3 - велика товщина).

Приклад. Побудова ліній користувача.

uses Graph, Crt;

var

gd, gm : integer; x1,x2,y1,y2: word; ch : char;

begin

gd := Detect;

InitGraph(gd,dm,'c:\tp\bgi');

if GraphResult <> 0 then Halt(1);

Randomize;

repeat

ClearDevice;

OutTextXY(200,10,’Випадкові лінії користувача’);

OutTextXY(140,20,’Зміна лінії - будь-яка клавіша, Esc-вихід');

SetLineStyle(4,Random(65535),1);

Line(10,100,GetMaxX,100);

ch := ReadKey;

until ch = #27;

CloseGraph;

end.

Зображення окружності, дуги еліпса й еліпса будується за допомогою наступних процедур:

окружність Circle(x, y, R);

дуга Arc(x, y, нач.знач.кута, кінц.знач.кута, R);

дуга еліпса й еліпс Ellipse(x, y, нач.знач.кута, кінц.знач.кута, Rx, Ry);

Розбивка окружності на сектори:

PieSlice(x, y, нач.знач.кута, кінц.знач.кута, R);

де X,Y:integer - центр окружності, чи дуги еліпса; “нач.знач.кута” і “кінц.знач.кута” – початковий і кінцевий кути в градусах, відлічувані від горизонтальної осі проти годинникової стрілки; R:word - радіус окружності чи дуги, Rx і Ry - півосі. Еліпс зображується при “нач.знач.кута”=0, ”кінц.знач.кута”=360.

Приклад побудови дуги, еліпса й окружності.

uses Graph,Crt:

var

gd, gm : integer; x,y :word;

begin

gd := Detect;

InitGraph(gd, gm, ’c:\tp\bgi’);

if GraphResult<>0 then Halt(1);

x := GetMax div 2; {координати центра}

y := GetMax div 2; {фігур}

SetColor(2);

OutTextXY(230,10,’Побудова окружності’);

Circle(x,y,150);

ReadKey; ClearDevice;

OutTextXY(240,10,’Побудова еліпса’);

Ellipse(x,y,0,360,180,120);

ReadKey; ClearDevice;

OutTextXY(200,10,’Побудова еліптичної дуги’);

Ellipse(x,y,0,180,180,120);

ReadKey; ClearDevice;

OutTextXY(250,10,’Побудова дуги’);

Arc(x,y,0,180,GetMaxY div 3);

ReadKey;

CloseGraph;

end.

Зображення прямокутника (внутрішня область збігається з кольором з фону):

процедура Rectangle(x1,y1,x2,y2:integer), де X1,Y1 і X2,Y2 відповідно координати лівого верхнього і нижнього правого кута.

Зображення заштрихованого за шаблоном прямокутника:

процедура Bar(x1,y1,x2,y2:integer), де X1,Y1 і X2,Y2 - координати діагоналі.

Зображення паралелепіпеда, лицьова сторона якого заштрихована за поточним шаблоном, а глибина задається:

процедура Bar(x1,y1,x2,y2:integer,d3:word,top:boolean), де X1,Y1 і X2,Y2 - координати діагоналі передньої грані, d3 - глибина в пикселях, top - задає режим відображення верхньої площини: True - відображати, False - не відображати. Для цієї процедури в Graph визначені дві константи:

TopOn = true; {верхня площина відображається}

TopOff = false; {верхня площина не відображається}

{Приклад побудови прямокутника, паралелепіпеда без верхньої площини і з верхньою площиною}

uses Graph,Crt;

var

gd, gm : integer; x1, x2, y1, y2 : word;

begin

gd := Detect;

InitGraf(gd,gm,’c:\tp\bgi’);

if GraphResult<>0 then Halt(1);

{координати вершин прямокутника по діагоналі}

x1 := GetMaxX div 4;

y1 := GetMaxY div 4;

x2 := 2*GetMaxX div 3;

y2:=GetMax div 5;

OutTextXY(210,50,’Звичайний прямокутник’);

OutTextXY(190,60,’(Продовження – будь-яка кл.)’);

Rectangle(x1,y1,x2,y2);

ReadKey; {в цьому випадку використовуємо як процедуру}

ClearDeviсe;

OutTextXY(210,50,’Залитий прямокутник’);

OutTextXY(190,60,’(Продовження – будь-яка кл.)’);

Bar(x1,y1,x2,y2);

ReadKey; ClearDevice;

OutTextXY(200,10,’Паралелепіпед без верхньої площини’);

OutTextXY(240,20,’(Продовження – будь-яка кл.)’);

Bar3D(x1,y1,x2,y2,(x2-x1) div 4, TopOff);

ReadKey; ClearDevice;

OutTextXY(200,10,’Паралелепіпед з верхньою площиною’);

OutTextXY(250,20,’(Вихід – будь-яка кл.)’);

Bar3D(x1,y1,x2,y2,(x2-x1) div 4, TopOn);

ReadKey;

CloseGraph;

end.

Завдання кольору ліній і тексту SetColor(color);

Завдання кольору фону SetBkColor(color);

Приклад керування кольором букв і фону.

uses Graph,Crt;

var

gd, gm : integer; ch : char; i : word;

begin

gd := Detect;

if GraphResults<>0 then Halt(1);

Randomize;

repeat

SetBkColor(i); SetColor(Random(GetMaxColor));

OutTextXY(190,10,’Послідовний перебір кольору фону’);

OutTextXY(210,20,’(Вибір кольору букв - випадковий)’);

OutTextXY(180,30,’(Продовження – будь-яка кл., вихід - Esc)’);

if i < GetMaxColor then inc(i)

else i := 0;

until ch = #27;

CloseGraph;

end.

Для зображення ламаних ліній, що задаються крапками зламу, використовується процедура

DrawPoly(кількість, координати);

Де ”кількість” - кількість крапок зламу, ”координати” - їхні координати. Координати задаються у виді масиву, кількість компонентів якого дорівнює кількості крапок зламу, а кожен компонент типу запис:

PointType=record

x, y : integer;{координати крапок}

end;

Процедура DrawPoly малює ламану лінію. Для одержання багатокутника потрібно першу та останню крапку зламу з'єднати.

Приклад побудови випадкових багатокутників.

uses Graph, Crt;

type

PointType = record

x,y : integer; {координати крапок}

end;

var

gd, gm : integer; i : byte; ch : char;

points : array[1..6] of pointtype; {масив вершин}

begin

gd := Detect;

InitGraph(gd,gm,’c:\tp\bgi’);

if GraphResults <> 0 then Halt(1);

Randomize;

SetColor(2);

OutTextXY(140,10,’Побудова випадкових кольорових багатокутників’);

SetColor(4);

OutTextXY(100,20,’(Для продовження – будь-яка кл., вихід - Esc)’);

ch := ReadKey;

if ch = #27 then begin

ClearDevice; Halt;

end;

repeat

ClearDevice;

for i := 1 to 6 do begin

{визначення випадкових координат}

points[i].x := Random(GetMaxX);

points[i].y := Random(GetMaxY);

end;

{для одержання багатокутника з'єднуємо}

{координати першої та останньої вершини}

points[6].x := points[1].x;

points[6].y := points[1].y;

SetColor(Random (15)+1);{вибір випадкового кольору}

DrawPoly(6, points); {будуємо багатокутник}

сh := ReadKey;

until ch = #27;

CloseGraph;

end.

Модуль Graph. Штрихування геометричних фігур.

Процедура для штрихування заданим стилем:

FloodFill(x,y, колір контуру);

де (x,y) - координати точки усередині замкнутого контуру чи поза ним. Штрихування складних геометричних фігур, що задаються координатами в масиві:

FillPoly(кількість, координати);

де ”кількість” - кількість крапок зламу, ”координати” - їхні координати. Координати задаються так само як у процедурі DrawPoly, але зв'язувати першу та останню вершини не потрібно, тому що процедура FillPoly малює замкнутий багатокутник, тобто перша та остання вершини з'єднуються відрізком.

Зображення заштрихованого еліпса:

FillEllipse(x,y,Rx,Ry);

де (x,y) - координати центра еліпса, Rx і Ry - півосі.

Завдання зразка штрихування:

SetFillStyle(тип штрихування, колір);

Тип штрихування обирається по таблиці 31.3.

Таблиця 31.3. Список констант для штрихування геометричних фігур.

Константа

Тип штрихування

Константа

Тип штрихування

0

Колір фону

7

Клітка

1

Поточний колір

8

Коса рідка клітка

2

-------

9

Коса часта клітка

3

//нормальна товщина

10

Рідка крапка

4

//подвоєна товщина

11

Часта крапка

5

\\подвоєна товщина

12

Визначення користувачем

6

\\нормальна товщина

Приклад штрихування фігур.

uses Graph,Crt;

type PointType=record

x, y : integer;

end;

var

gd, gm : integer; i, x1, x2, y1, y2 : word;

points : array[1..4] of PointType;

begin

gd := Detect;

InitGraph(gd, gm, ’c:\tp\bgi’);

if GraphResults<>0 then Halt(1);

OutTextXY(240,10,’Кругова діаграма’);

SetColor(1); SetLineStyle(0,0,3); {стиль лінії}

SetFillStyle(10,2); {вибір стилю заповнення}

PieSlice(GetMaxX div 2, GetMaxY div 2, 47, GetMaxY div 3);

SetFillStyle(11,4);

PieSlice(GetMaxX div 2, GetMaxY div 2, 47, 170, GetMaxY div 3);

SetFillStyle(9,5);

PieSlice(GetMaxX div 2, GetMaxY div 2, 170, 210, GetMaxY div 3);

SetFillStyle(8,6);

PieSlice(GetMaxX div 2, GetMaxY div 2, 210, 260, GetMaxY div 3);

SetFillStyle(7,7);

PieSlice(GetMaxX div 2, GetMaxY div 2, 260, 360, GetMaxY div 3);

ReadKey; ClearDevice; SetColor(2);

OutTextXY(240,10,’Заповнення еліпса’);

SetFillStyle(1,8);

FillEllipse(GetMaxX div 2,GetMaxY div 2, 200, 150);

ReadKey; ClearDevice; SetColor(3);

OutTextXY(220,10,’Заповнення еліптичного сектора’);

SetFillStyle(6,4);

Sector(GetMaxX div 2,GetMaxY div 2, 45, 90, 200, 150);

ReadKey; ClearDevice;

OutTextXY(250, 10, ‘Заповнення граней паралелепіпеда’);

x1 := GetMaxX div 4;

y1 := GetMaxY div 3;

x2 := 3*GetMaxX div 4;

y2 := 2*GetMaxX div 3;

SetColor(2); SetFillStyle(2,4);

Bar3D(x1, y1, x2, y2, (x2-x1) div 4, TopOn);

SetFillStyle(6,3);

SetFillStyle(3,4);

FloodFill(x1+50,y1-10,2);

FloodFill(x2+10,y2-50,2);

ReadKey; ClearDevice;

OutTextXY(220, 10, ’Заповнення прямокутника’);

points[1].x := GetMaxX div 3;

points[2].x := 2*GetMaxX div 3;

points[3].x := 2*GetMaxX div 3;

points[4].x := GetMaxX div 3;

points[1].y := GetMaxY div 3;

points[2].y := GetMaxY div 3;

points[3].y := 3*GetMaxY div 3;

points[4].y := 3*GetMaxY div 3;

FillPoly(4, Points);

ReadKey;

CloseGraph

end.

Збереження і виведення зображень на екран. Одержання зображення, що рухається.

Модуль Graph дозволяє запам'ятовувати в буфері і відновлювати з нього фрагменти зображень на екрані. Зображення для збереження міститься в динамічну область пам'яті, розмір якої повинний відповідати розміру зображення в прямокутній області екрана в байтах.

Для обчислення розміру використовують функцію:

ImageSize(x1, y1, x2, y2:integer):word;

де X1,Y1 і Х2,Y2 - координати лівого верхнього і правого нижнього кутів прямокутника частини екрана, у якому розташоване зображення. Розмір зображення, що зберігається, не повинний бути більш 64 kb.

Для збереження зображення процедурою GetMem в області динамічної пам'яті виділяють буфер обчисленого розміру:

GetMem(p,Size);

де p - виділений буфер, Size - його розмір у байтах.

Зображення частини екрана міститься в буфер (р^) за допомогою процедури:

GetImage(x1, y1, x2, y2, p^);

де Х1, У1, Х2, У2 - координати фрагмента.

Процедура

PutImage(x, y, p^, вид);

виводить на екран раніше збережене в буфері (р^) зображення, де Х, У -координати лівого верхнього кута виведеного зображення;

параметр “вид”:word визначає яким чином виводиться зображення щодо наявного на екрані. Значення цього параметра наступні (задається ім'ям чи значенням):

NormalPut = 0 - очищується область і виводиться зображення;

XorPut = 1 - зображення затирається, а при повторному використанні виводиться в іншому (в заданому) місці;

OrPut = 2 - накладення зображення;

AndPut = 3 - перетинання двох зображень;

NotPut = 4 - зображення негативне.

Отже, одержання зображення, що рухається, зводиться до наступних – операцій (рис. 31.1).

Рисунок 31.1. Одержання зображення, що рухається

Size := ImageSize(x1,y1,x2,y2);- визначаємо розмір зображення в байтах;

GetMem(p,Size); - виділяємо область динамічної пам'яті для збереження зображення;

GetImage(x1,y1,x2,y2,p^); - поміщаємо зображення у виділену пам'ять (у р^);

PutImage(x1,y1,p^,1); - затираємо зображення;

PutImage(x2,y2,p^,1) - малюємо зображення в іншім місці.

Приклад руху фігури.

uses Graph, Crt;

var

gd, gm : integer;

Size : word; x1, y1, x2, y2 : word; p : pointer;

begin

gd := Detect;

InitGraph(gd, gm, ’c:\tp\bgi’);

if GraphResult <> 0 then Halt(1);

OutTextXY(120,1,’Одержання зображення, що рухається,‘, ‘(натисни будь-яку клавішу)’);

ReadKey;

{координати прямокутника}

x1 := GetMax div 300; y1 := GetMax div 200;

x2 := GetMax div 10; y2 := 2*GetMax div 10;

{малюємо прямокутник}

Rectagle(x1,y1,x2,y2);

Size := ImageSize(x1,y1,x2,y2);

GetMem(p,Size);

GetImage(x1,y1,x2,y2,p^);

{затираємо зображення}

PutImage(x1,y1,p^,XorPut);

{малюємо зображення в іншому місці}

PutImage(x2+500,y2+250,p^,1); {замість XorPut можна ставити 1}

ReadKey;

CloseGraph;

end.

Питання для контролю:

  1. Доступ до графічних процедур і функцій.

  2. Ініціалізація графіки і перехід у графічний режим.

  3. Автовизначення графічного режиму.

  4. Визначення і видача помилок при ініціалізації графіки.

  5. Виведення тексту в графічному режимі.

  6. Виведення числа в графічному режимі.

  7. Система координат і визначення максимальної кількості по осях.

  8. Очищення графічного екрана.

  9. Визначення поточного положення покажчика і його переміщення.

  10. Виведення крапки заданого кольору.

  11. Побудова ліній.

  12. Зображення окружності, дуги, дуги еліпса й еліпса.

  13. Зображення прямокутника.

  14. Зображення заштрихованого за шаблоном прямокутника.

  15. Зображення паралелепіпеда з заштрихованою лицьовою стороною.

  16. Завдання кольору ліній, тексту і фону в графічному режимі.

  17. Зображення ламаних ліній, що задаються крапками зламу.

  18. Штрихування геометричних фігур заданим стилем.

  19. Зображення заштрихованого еліпса.

  20. Завдання зразка штрихування.

  21. Визначення розміру зображення.

  22. Виділення буферу в області динамічної пам'яті для збереження зображення.

  23. Переміщення зображення у виділений буфер динамічної пам'яті.

  24. Виведення на екран збереженого в буфері зображення.

  25. Операції одержання зображення, що рухається.