Урок № 33
Тема: Использование процедур в графике. Разбор и решение задач с использование графического модуля и процедур.
Вопросы темы:
1. Процедуры FloodFill и SetFillStyle
2. Процедуры Rect. Bar, SetFillStyle и Rectangle
3. Процедуры LineRel, MoveRel, MoveTo.
Процедуры FloodFill и SetFillStyle
Разноцветные концентрические окружности. Для закраски замкнутой области используется процедура FloodFill, три целочисленных параметра которой задают начальную точку закраски и код цвета ограничивающей область линии. Цвет, которым будет производиться закраска, ничего общего не имеет с цветом, задаваемым процедурой SetColor. Цвет закраски задается вторым параметром процедуры SetFillStyle. Первый параметр этой процедуры (задающий узор для закраски) на первых порах будем задавать равным единице (что соответствует сплошной закраске).
PROGRAM Primer_6;
uses Graph;
const CX=320;
CY=240;
var Gd,Gm: Integer;
i : Integer;
BEGIN
Gd:=VGA; Gm:=VGAHi; InitGraph (Gd,Gm,'..\bgi');
If GraphResult=grOk
then begin
For i:=0 to 23 do
Circle (CX,CY,i*10);
For i:=0 to 23 do
begin
SetFillStyle (1,i MOD 16);
{ Закрашивать до границы белого цвета }
FloodFill (CX,CY+i*10-5,White)
end;
Readln
end
END.
PROGRAM Primer_7;
uses Graph;
var grDriver: Integer;
grMode : Integer;
i,x,y : Integer;
{ ----------------------------------- }
PROCEDURE Rect (x,y,x1,y1: Integer);
{ Рисует прямоугольник, у которого левый
нижний угол }
{ имеет координаты (x,y), а правый верхний - (x1,y1) }
BEGIN
Line (x,y,x,y1); { Левая сторона }
Line (x1,y,x1,y1); { Правая сторона }
Line (x,y1,x1,y1); { Верхняя сторона }
Line (x,y,x1,y) { Нижняя сторона }
END;
{ --- }
BEGIN
GrDriver:=VGA; GrMode:=VGAHi;
InitGraph (grDriver,grMode,'..\bgi');
If GraphResult=grOk
then begin
For i:=1 to 15 do
begin
x:=i*30; y:=i*25; SetColor (i);
Rect (x,y,x+50,y+60)
end;
ReadLn
end
END.
Рисование прямоугольников - часто встречающаяся проблема, и поэтому неудивительно, что существует стандартная процедура, работающая так же, как и созданная нами ниже процедура Rect. Она называется Rectangle.
Процедуры Rect. Bar, SetFillStyle и Rectangle
Для рисования "заполненных" прямоугольников используется процедура Bar. Так же, как и для процедуры Rectangle, мы должны указать четыре числа - координаты двух противоположных углов прямоугольника. (Для процедуры Bar цвет задается не с помощью SetColor, а с помощью SetFillStyle!).
PROGRAM Primer_8;
uses Graph;
const Step=35;
var grDriver: Integer;
grMode : Integer;
i,x,y : Integer;
{ ------------------------------- }
PROCEDURE Square (x,y: Integer);
{ Рисует цветастый квадрат, центр которого }
{ имеет координаты (x,y) }
var i,d: Integer;
BEGIN
For i:=15 downto 0 do
begin
SetFillStyle (SolidFill,i); d:=i*3+2;
Bar (x-d,y-d,x+d,y+d)
end
END;
{ --- }
BEGIN
GrDriver:=VGA; grMode:=VGAHi;
InitGraph (grDriver,grMode,'..\bgi');
If GraphResult=grOk
then begin
For i:=0 to 10 do
{ На "побочной" диагонали - 11 точек }
begin
x:=50+i*Step; y:=50+(10-i)*Step;
SetColor(i); Square(x,y)
end;
ReadLn
end
END.
Процедуры LineRel, MoveRel, MoveTo.
При рисовании сложных изображений, содержащих много отрезков, возникает довольно противная проблема - вычислять координаты всех точек. Если использовать процедуру LineRel, то достаточно указывать смещения по обеим координатам относительно текущей точки. Для относительного перемещения без рисования используется процедура MoveRel. Для задания начальных значений координат текущей точки используется процедура MoveTo.
Квадратная спираль.
PROGRAM Primer_9;
uses Graph;
const CenterX=320;
CenterY=240;
d=12;
var grDriver: Integer;
grMode : Integer;
i,L : Integer;
{ ------------------------------- }
PROCEDURE Vitok (L,dL: Integer);
{ Начиная от текущей точки, рисует виток спирали }
{ из четырех отрезков увеличивающейся длины }
{ L - длина первого отрезка }
{ dL - приращение длины для каждого из следующих отрезков }
BEGIN
LineRel (L,0); { Сдвинуться вправо }
LineRel (0,-(L+dL)); { Сдвинуться вверх }
LineRel (-(L+2*dL),0); { Сдвинуться влево }
LineRel (0,L+3*dL); { Сдвинуться вниз }
END;
{ --- }
BEGIN
grDriver:=VGA; grMode:=VGAHi;
InitGraph (grDriver,grMode,'..\bgi');
If GraphResult=grOk
then begin
{ Сделать текущей точкой центр экрана }
MoveTo (CenterX,CenterY);
L:=1; { Начальная длина отрезка }
For i:=1 to 10 do { 10 витков спирали }
begin Vitok (L,d); L:=L+4*d end;
ReadLn
end
END.
Пример 5. Небольшой городок.
PROGRAM Domiki;
uses Graph;
var grDriver: Integer;
grMode : Integer;
i,j : Integer;
{ ------------------------------ }
PROCEDURE Domik (x,y: Integer);
{ Рисует домик, у которого левый нижний угол }
{ имеет координаты (x,y) }
const dx=60; { Ширина фасада }
dy=40; { Высота фасада }
dx2=dx DIV 2;
dy2=dy DIV 2;
wx=16; { Ширина окна }
wy=22; { Высота окна }
wx2=wx DIV 2;
wy2=wy DIV 2;
BEGIN
Rectangle (x,y,x+dx,y-dy); MoveTo (x,y-dy);
Linerel (dx2,-dx2); { Левый скат крыши }
Linerel (dx2,dx2); { Левый скат крыши }
Rectangle (x+dx2-wx2,y-dy2-wy2,x+dx2+wx2,y-dy2+wy2); { Окно }
MoveTo (x+dx2,y-dy2); { Центр фасада (и окна) }
LineRel (0,wy2); { Вертикальная часть рамы окна }
MoveTo (x+dx2-wx2,y-dy2); { Центр левой части рамы окна }
LineRel (wx,0); { Горизонтальная часть рамы окна }
SetFillStyle (SolidFill,Red);
FloodFill (x+1,y-1,White);
SetFillStyle (SolidFill,Blue);
FloodFill (x+dx2,y-dy-1,White)
END;
{ --- }
BEGIN
grDriver:=VGA; grMode:=VGAHi;
InitGraph (grDriver,grMode,'..\bgi');
If GraphResult=grOk
then begin
For i:=1 to 6 do
For j:=1 to 5 do
Domik (i*80,j*80);
ReadLn
end
END.
Если Вас интересуют другие графические процедуры или функции, то Вам следует обратиться к системе "помощи" (Help). Для этого в меню Help выберите пункт Standard units. Среди всего прочего Вы увидите список названий стандартных модулей (неважно, что вы не знаете, что это такое). Если установить курсор на слово Graph (этого можно достигнуть и с помощью клавиши Tab) и нажать Enter, то на экране появится общая информация о модуле Graph. Для продолжения нам предлагается два выбора:
Go to GRAPH.TPU Functions and Procedures
Go to GRAPH.TPU Constants and Types
Если выбрать пункт "Перейти к константам и типам GRAPH.TPU", то Вы сможете добраться до такой полезной информации, как названия графических режимов и их разрешение, названия цветов, названия стилей закраски и т.п. На случай, если Вам захочется там что-нибудь поискать, приведем перевод названий некоторых пунктов соответствующего меню:
Color Constants Цветовые константы
Fill Pattern Constants Константы для образцов закраски
Graphics Drivers Графические драйверы
Graphics Modes for Each Driver Графические режимы для каждого
Драйвера.
Выбрав же пункт "Перейти к процедурам и функциям GRAPH.TPU", мы увидим внушительный список названий графических процедур и функций. Если поместить курсор на название приглянувшейся Вам процедуры (или функции), и нажать "перевод строки", то Вы увидите краткое описание этой процедуры (функции), и в конце - предложение посмотреть пример. (Если, скажем, Вы читаете информацию о процедуре Ellipse, то в самом конце Вы увидите слова
Sample Code: Ellipse.PAS Если установить курсор на слова Ellipse.PAS и нажать "перевод строки", то на экране Вы увидите текст программы, иллюстрирующий применение этой процедуры). Эта информация может пригодиться даже тем, кто не знает ни одного английского слова - Вы увидите, сколько у процедуры параметров и какие у этих параметров типы; Вы можете обычным образом (клавишами управления курсором при нажатой клавише Shift) отметить текст примера, скопировать в пустое окно и запустить.