16. Графические средства языка Паскаль

Монитор персонального компьютера может работать в двух режимах: тек­стовом и графическом. Все, что вы делали до сих пор, вы делали в текстовом ре­жиме. Текстовый экран содержит 2000 знакомест - 25 строк по 80 позиций, в каждом знакоместе может быть выведен один символ. Графический экран состо­ит из маленьких точек - пикселов, каждый из которых закрашен в какой-либо цвет. Для работы в графическом режиме существует обширная библиотека про­цедур и функций, находящихся в модуле Graph. Структуру модуля и правила создания пользовательских модулей мы рассмотрим несколько позже. Чтобы ис­пользовать стандартные модули, вам достаточно знать лишь один оператор : USES модуль , ... ;

Этот оператор должен быть первым оператором в программе, в нем перечис­ляются все модули, используемые данной программой; в частности, чтобы рабо­тать с графикой, вам достаточно записать USES Graph;. Теперь рассмотрим графические средства, предоставляемые этим модулем. Здесь описаны только наиболее употребительные и наиболее полезные, по мнению автора, средства. Тот, кто хочет изучить все возможности модуля Graph, может сделать это, поль­зуясь справочной службой среды Turbo Pascal (или Borland Pascal).

1. PROCEDURE InitGraph(VAR GraphDriver,GraphMode: Integer; PathToDriver: STRING); - эта процедура инициализирует графический режим, т.е. переключает монитор из текстового режима в графический. Любые графиче­ские процедуры и функции могут быть выполнены только в графическом режи­ме. Перед вызовом InitGraph необходимо первому аргументу присвоить значе­ние DETECT (константа, описанная в модуле Graph). PathToDriver - это строка, содержащая путь к файлу - графическому драйверу, для мониторов от EGA до SVGA это файл EGAVGA.BGI. Графические драйверы всегда содержатся в ди­ректории, где находится сам Turbo Pascal (обычно в поддиректории BGI). Вы можете либо отыскать на диске этот файл и в программе правильно задать путь к нему, например, 'D:\TP\BGI', либо иметь этот файл в вашей рабочей директо­рии, тогда путь задается пустой строкой. Если ни то, ни другое не сделано, гра­фический режим не будет инициализирован.

2. PROCEDURE CloseGraph; - закрывает графический режим.

3. FUNCTION GetMaxX : Integer; .

4. FUNCTION GetMaxY : Integer; - возвращают соответственно номер са­мого правого и самого нижнего пиксела экрана. Пикселы нумеруются от 0 до GetMaxX слева направо и от 0 до GetMaxY сверху вниз. Разрешение графиче­ского экрана зависит от типа монитора и от выбранного графического режима. Например, для монитора VGA максимальное разрешение 640 х 480, т.е. GetMaxX вернет 639, а GetMaxY - 479.

5. PROCEDURE SetBkColor(Co/or: Word); - устанавливает фоновый цвет, после ее выполнения весь экран будет закрашен в цвет Co/or. Цветовая палитра также зависит от типа монитора и выбранного графического режима, но стан­дартная палитра для цветного монитора включает 16 цветов:

0 - Black        1 - Blue 2 - Green 3 - Cyan

4 - Red 5 - Magenta 6 - Brown 7 - LightGray

8 - DarkGray 9 - LightBlue        10 - LightGreen 11 - LightCyan 12 - LightRed  13 - LightMagenta 14 - Yellow       15 - White Приведенные названия - это имена констант, описанных в модуле Graph; вы можете использовать их или номера цветов.

6. PROCEDURE SetViewPort(x1,y1,x2,y2: Integer; C/ip: Boolean); - устанав­ливает графическое окно. x1,y1,x2,y2 - координаты соответственно левого верх­него и правого нижнего углов окна. После выполнения этой процедуры пикселы будут отсчитываться от левого верхнего угла окна. Логический параметр C/ip определяет, следует ли усекать изображения на границах окна. Выполнять этупроцедуру вовсе не обязательно, по умолчанию графическое окно занимает весь экран.

7. PROCEDURE ClearDevice; - закрашивает экран фоновым цветом.

8. PROCEDURE PutPixelpCY: Integer; Color: Word); - закрашивает пиксел с координатами X,Y цветом Color.

9. FUNCTION GetPixel(X,Y: Integer): Word; - возвращает цвет пиксела с ко­ординатами X,Y.

10. PROCEDURE SetColor(Color : Word); - устанавливает цвет линий, все выводимые на экран линии будут иметь цвет Color до выполнения следующей процедуры SetColor.

11. PROCEDURE SetLineStyle(LineStyle, Pattern, Thickness: Word); - уста­навливает стиль линий, действует для всех выводимых линий до выполнения SetLineStyle с другими аргументами. Параметр LineStyle может принимать сле­дующие значения:

0 - SolidLn - сплошная линия;

1 - DottedLn - пунктирная линия;

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

3 - DashedLn - штриховая линия;

4 - UserBitLn - линия, задаваемая программистом.

Если стиль линии - 4, то форма линии определяется вторым параметром процедуры - Pattern. Толщина линии может принимать всего два значения: 1 - NormWidth - тонкая линия; 3 - ThickWidth - жирная линия.

12. PROCEDURE Line(x 1,y1,x2,y2: Integer); - рисует отрезок прямой от точ­ки с координатами x1,y1 до точки x2,y2.

13. PROCEDURE MoveTo(x,y: Integer); - перемещает графический курсор в точку x,y. Графический курсор не виден на экране, но ряд процедур использует текущее положение графического курсора.

14. PROCEDURE LineTo(x,y: Integer); - рисует отрезок от текущей точки (текущего положения графического курсора) до точки x,y.

15. PROCEDURE MoveRel(Dx,Dy: Integer);- перемещает графический кур­сор на Dx по горизонтали и на Dy по вертикали.

16. PROCEDURE LineRel(Dx,Dy: Integer); - рисует отрезок от текущей точ­ки до точки со смещением Dx,Dy.

17. FUNCTION GetX: Integer; и

18. FUNCTION GetY: Integer; - возвращают текущие координаты графиче­ского курсора.

19. PROCEDURE Rectangle(x1,y1,x2,y2: Integer); - рисует прямоугольник, x1 ,y1 - координаты левого верхнего угла, x2,y2 - координаты правого нижнего угла.

20. PROCEDURE Circle(X,Y: Integer; R: Word); - рисует окружность радиу­са R с центром в точке X,Y.

21. PROCEDURE Ellipse(X,Y: Integer; f1f2RxRy: Word); - рисует дугу эл­липса с полуосями Rx,Ry и центром в точке X,Y от угла fl до угла f2 (углы зада­ются в градусах).

22. PROCEDURE Arc(X,Y: Integer; f1f2,R: Word); - рисует дугу окружности радиуса R с центром в точке X,Y от углаf1 до угла f2.

23. PROCEDURE SetFillStyle(Pattern,Co/or: Word); - устанавливает способ закраски. Параметр Pattern может принимать следующие значения: 0 - EmptyFill - не закрашивать, 1 - SolidFill - сплошная закраска, 2 - LineFill, 3 - LtSlashFill,

4 - SlashFill, 5 - BkSlashFill, 6 - LtBkSlashFill,7 - HatchFill, 8 - XHatchFill, 9 - InterleaveFill, 10 - WideDotFill, 11 - CloseDotFill.

24. PROCEDURE Bar(x1,y1,x2,y2: Integer); - рисует закрашенный прямо­угольник, используя способ закраски, установленный процедурой SetFillStyle.

25. PROCEDURE FillEllipse(X,Y: Integer; Rx,Ry: Word); - рисует закрашен­ный эллипс.

26. PROCEDURE Sector(X,Y: Integer; f1J2RbcRfy: Word); - рисует закрашен­ный эллиптический сектор.

27. PROCEDURE PieSlice(X,Y: Integer; f1f2R: Word); - рисует закрашенный круговой сектор.

28. PROCEDURE FloodFill(X,Y: Integer; Border: Word); - закрашивает замк­нутую область, ограниченную линией цвета Border, X,Y - координаты любой внутренней точки области. Используется способ закраски "заливка жидкостью", поэтому, если ограничивающая линия имеет разрывы, "жидкость" выльется и закрасит все области экрана, которые сможет. Автор рекомендует самостоятель­но провести эксперимент с этой процедурой.

29. PROCEDURE SetTextStyle(Font,Direction,Size: Word); - устанавливает способ вывода текста. Font - номер графического шрифта, принимающий значе­ния 0 - DefaultFont , 1 - TriplexFont , 2 - SmallFont , 3 - SansSerifFont ,

4 - GothicFont. Нулевой шрифт - стандартный и поддерживается всегда. Если вы используете штриховые шрифты с 1-го по 4-й, то должны иметь в вашей рабо­чей директории шрифтовые файлы TRIP.CHR , LITT.CHR , SANS.CHR , GOTH.CHR (те из них, которые вам нужны). Параметр Direction определяет на­правление вывода текста (слева направо или сверху вниз) и принимает значения 0 - HorizDir ,1 - VertDir. Параметр Size определяет размер символов и изменяет­ся от 1 до 10.

30. PROCEDURE OutText(S: STRING); - выводит текст на графический эк­ран, используя текущие координаты графического курсора (процедура WRITE[LN] в графическом режиме не работает).

31. PROCEDURE OutTextXY(X,Y: Integer; S: STRING); - выводит текст на графический экран, используя координаты X,Y.

32. PROCEDURE SetTextJustify(Horiz, Vert: Word); - устанавливает способ позиционирования текста. Параметр Horiz может принимать значения:

0 - LeftText     - по левому краю,

1 - CenterText - по середине текста,

2 - RightText   - по правому краю. Параметр Vert может принимать значения:

0 - BottomText - по нижнему краю,

1 - CenterText - по середине текста,

2 - TopText      - по верхнему краю.

Не пренебрегайте этой процедурой, если хотите аккуратно вывести подписи к вашему рисунку.

33. FUNCTION TextWidth(S: STRING): Word; - возвращает длину текста в

пикселах.

34. FUNCTION TextHeight(S: STRING): Word; - возвращает высоту текста

в пикселах.

35. PROCEDURE SetVisualPage(Page : Word); - устанавливает видимую графическую страницу (если в данном графическом режиме есть несколько ви­деостраниц). Page - номер страницы, равный 0,1 и т.д.

36. PROCEDURE SetActivePage(Page : Word); - устанавливает текущую графическую страницу, куда будет направлен весь вывод. Две последние проце­дуры могут быть использованы для создания мультипликации.

37. PROCEDURE SetGraphMode(Mode: Integer); - устанавливает графиче­скую моду. Большинство графических драйверов допускает несколько мод. Ка­кой графический драйвер задействован в данном компьютере, можно узнать по значению параметра GrDriver после выполнения процедуры InitGraph. При­сваивая этой переменной значение DETECT, мы не задаем никакого драйвера, а лишь указываем, что процедура сама должна определить этот драйвер. В Паскале определены следующие константы драйверов: DETECT=0, CGA=1, MCGA=2, EGA=3, EGA64=4, EGAMONO=5, IBM8514=6, HERCMONO=7, ATT400=8, VGA=9, PC3270=10. При успешном выполнении процедура InitGraph возвра­тит одно из этих значений через параметр GrDriver. Параметру GrMode присваи­вается значение установленной графической моды (от 0 до 4), причем устанавли­вается старшая мода. У драйвера VGA есть три моды, различающиеся разреше­нием экрана и количеством видеостраниц:

0 - 640 х 200, 4 страницы,

1 - 640 х 350, 2 страницы,

2 - 640 х 480, 1 страница.

Именованные константы для графических мод также описаны в модуле Graph; так, для перечисленных выше мод это: VGALo, VGAMed, VGAHi.

38. FUNCTION GetGraphMode : Integer; - возвращает установленную гра­фическую моду.

39. PROCEDURE RestoreCrtMode; - устанавливает текстовый режим мони­тора. Эта процедура совместно с SetGraphMode может использоваться для от­ладки графических программ. Предположим, что мы написали, но пока еще не отладили графическую программу. Мы хотим вывести какую-либо информацию, вычисляемую программой, на экран, но использовать для вывода процедуру

OutText довольно затруднительно. Организуем нашу программу следующим об­разом :

... InitGraph ...  { здесь мы хотим вывести информацию } RestoreCrtMode; WRITELN(...

{ вернемся в графику } SetGraphMode(GetGraphMode); ...

40. FUNCTION GraphResult :Integer; - возвращает код завершения послед­ней графической операции; если этот код равен grOK (=0), то операция выпол­нена успешно, в противном случае произошла ошибка.

Чтобы продемонстрировать некоторые из графических возможностей языка Паскаль, напишем программу, рисующую график функции cos x на отрезке [0,6л]. USES Graph;

CONST ScreenColor = DarkGray; {цвет экрана}

LineColor   = Yellow;      {цвет кривой}

TextColor   = White;        { цвет подписей}

AxisColor = LightCyan; {цвет координатных осей} CONST n = 200; {количество отрезков в графике}

LeftBlank    = 100; {отступ слева}

RightBlank   = 100; {отступ справа}

TopBlank     = 100; { отступ сверху}

BottomBlank = 60 ; {отступ снизу}

TicSize = 5;    {размер делений на осях}

PowerSize     = 3;    {размер цифры 2 (показатель степени)}

TicsNumY    = 10;  {количество делений на оси Y}

TicsNumX = 6; {количество делений на оси Y} CONST x1=6*Pi;

FUNCTION f(x:REAL):Real; BEGIN f:=Sqr(Cos(x)); END; VAR GrDriver,GrMode,Lx,Ly,Px,Py : Integer;

i : Word;

s : STRING;

Mx,My,x : Real;

BEGIN { инициализируем графический режим}

GrDriver:=DETECT; InitGraph(GrDriver,GrMode,''); { закрасим экран фоновым цветом} SetFillStyle(1,ScreenColor); Bar(0,0,GetMaxX,GetMaxY); { вычислим длины осей и положение начала координат} Lx:=GetMaxX+1-LeftBlank-RightBlank; Ly:=GetMaxY+1-TopBlank-BottomBlank; Px:=LeftBlank; Py:=GetMaxY-BottomBlank;

{ нарисуем оси} SetColor(AxisColor);

MoveTo(LeftBlank,TopBlank-1); LineRel(0,Ly); LineRel(Lx,0);

{ оцифруем ось X}

SetTextJustify(CenterText,TopText);

FOR i:=1 TO TicsNumX DO BEGIN

MoveTo(LeftBlank+i*Lx DIV TicsNumX,Py); LineRel(0,TicSize);

IF i=1 THEN s:='' ELSE Str(i,s); MoveRel(0,2); OutText(s+'Pi');

END;

{ оцифруем ось Y}

SetTextJustify(RightText,CenterText); FOR i:=1 TO TicsNumY DO BEGIN

MoveTo(Px,Py-i*Ly DIV TicsNumY); LineRel(-TicSize,0);

Str(i/10:3:1,s); MoveRel(-2,0); OutText(s);

END;

{ выведем пояснительный текст}

SetTextJustify(CenterText,CenterText); SetColor(TextColor); MoveTo(LeftBlank+Lx DIV 2,TopBlank DIV 2); OutText('график функции Cos(x)'); { выведем показатель степени}

MoveRel(TextWidth('график функции Cos(x)') DIV 2-

TextWidth('(x)'),TextHeight('s'));

SetTextStyle(SmallFont,0,PowerSize); OutText('2'); { вычислим масштабы по X и Y}

Mx:=Lx/x1; My:=Ly; { нарисуем график}

SetLineStyle(0,0,3); SetColor(LineColor); MoveTo(Px,Py-Ly);

FOR i:=1 TO n DO BEGIN

x:=i*x1/n; LineTo(Px+Round(Mx*x),Py-Round(My*f(x)));

END;

{ сделаем задержку}

READLN;

{ перейдем в текстовый режим} CloseGraph;

END.

Это неплохая программа, но автор хотел бы предостеречь от ее бездумного использования как эталона во всех случаях. Она использует априорную инфор­мацию о виде изображаемой функции: минимальное значение функции = 0, мак­симальное значение функции = 1, начало координат находится в точке пересече­ния осей и т.п. В ваших программах все может быть не так.