Построение простейших геометрических фигур

Линии и точки. Для построения изображений часто бывает необходимо задавать стартовую точку этого построения. Для этой цели в графике Паскаля предусмотрено понятие «Текущий указатель» (CP – CURRENT POINTER), который определяет положение «невидимого курсора». Для перемещения СР в границах экрана монитора, который, как мы знаем, представляет собой первую четверть декартовой системы координат, имеется ряд процедур и функций. В первую очередь это процедура MoveTo (X, Y), которая перемещает текущий указатель (CP) в точку с координатами X, Y. Например, процедура MoveTo (200,100) переместит текущий (невидимый) указатель в точку экрана с координатами (200, 100).

Для рисования прямых линий применяются три процедуры:

- Line (X, Y, X1, Y1:integer) рисует линию от точки с координатами (X, Y) к точке (X1,Y1);

- LineTo (X, Y) строит линию из точки текущего положения указателя в точку с координатами X, Y;

- LineRel (dX, dY) строит линию от точки с текущим положением указателя в точку (CpX + dX, CpY + dY), где CpX и CpY - текущие координаты Cp. Цвет линии задается оператором SetColor (Цвет).

TurboPascal позволяет вычерчивать линии самого различного стиля: тонкие, широкие, штриховые, пунктирные и т. д. Установка стиля производится процедурой SetLineStyle (Стиль: word; pattern: word; Толщина: word). Стили линий представлены в таблице 3.

Таб.3. Стили линий

Константа Значение Описание
SolidLn DottedLn CenterLn DachedLn Непрерывная линия Линия из точек Линия из точек и тире Штриховая линия

Толщина линии представлена в таблице 4.

Константа Значение Описание      
SolidLn TchickWidth Нормальная толщина Жирная линия      
           

Какие бы изображения не выводились на экран, все они построены из точек. Для вывода на экран точки используется процедура РutPixel (X, Y, Цвет), которая рисует на дисплее точку (пиксель) с координатами X, Y и цветом "Цвет".

Ниже следует программа, которая заполняет экран монитора точками, цвет которых и их расположение задается датчиком случайных чисел Randomize:

Uses Crt, GRAPH;

Var X, Y, c, d, m: Integer;

вegin

d:=Detect; InitGRAPH(d, m, '');

randomize; ClearViewPort;

while not keypressed do

begin

Delay (100);

X:=Random (640);

Y:= Random (480);

c:= Random (15);

putpiXel (X, Y, c)

end;

CloseGRAPH;

end.

Прямоугольники. Для построения прямоугольных фигур имеется несколько процедур. Первая из них - процедура Rectangle (X1, Y1, X2, Y2) вычерчивания прямоугольника цветом, заданным предварительно оператором SetColor. Для построения закрашенного прямоугольника используется процедура: Bar (X1, Y1, X2, Y2). Помимо прямоугольников возможно построение и пространственных прямоугольных фигур с помощью процедуры Bar3D (X1, Y1, X2, Y2 : integer, Depth: Word; Top: Boolean), где X1, Y1, X2, Y2 определяют положение прямоугольника, являющегося «передней» гранью пространственной фигуры, а параметр Depth определяет "глубину" 3-х мерного прямоугольника, который обычно равен (X2 - X1 + 1) div 4. (Куб). Параметр Top определяет положение вершины прямоугольника относительно передней грани. Цвет заполнения для Bar и Bar3D устанавливается процедурой SetFillStYle.

Дуги и окружности. Процедура вычерчивания окружности текущим цветом имеет следующий формат: Circle (X, Y, Radius: word) где X и Y - центр окружности, а Radius - ее радиус. В ряде случаев, в частности для создания псевдообъемных фигур, используются дуги. Их можно вычертить с помощью процедуры Arc (X, Y: integer; StAngle, EndAngle, Radius: word) где X, Y - центр окружности, StAngle и EndAngle - начальный и конечный угол дуги, заданный в градусах, Radius - радиус дуги.

Эллипсы и сектора. Для построения эллиптических дуг предназначена процедура Ellipse(X, Y, StAngle, EndAngle, XR, YR), где X, Y - центр эллипса в дисплейных координатах, XR и YR - горизонтальная и вертикальная оси. Дуга эллипса вычерчивается от начального угла StAngle до конечного угла EndAngle текущим цветом. Фон внутри эллипса совпадает с фоном экрана. Исходя из математических фактов связи эллипса с окружностью, можно рисовать дуги и окружности (а не эллипса), если взять в этой процедуре равными значения XR и YR. С другой стороны, для построения полного эллипса в процедуре Ellipse(X, Y, StAngle, EndAngle, XR, YR) нужно положить StAngle = 0, EndAngle=360.

Чтобы создать закрашенный эллипс, используется специальная процедура FillEllipse (X, Y, XR, YR), где X, Y - центр эллипса в дисплейных координатах, XR и YR - горизонтальная и вертикальная оси. Заполнитель устанавливается процедурой SetFillStyle. Очевидно, что для вычерчивания не закрашенного эллипса необходимо в процедуре SetFillStyle указать цвет фона.

Можно создать и заполнить сектор в эллипсе. Для этого используется процедура Sector (X, Y, StAngle, EndAngle, XR, YR), где X, Y - центр, XR, YR - горизонтальный и вертикальный радиусы, StAngle и EndAngle - начальный и конечный угол (в градусах).

Ниже представлена программа работы с различными типами линий и закрашивания фигур различными цветами.

Uses GRAPH;

Var i, d: integer;

begin

d := detect;

InitGRAPH (d, i, 'G/Work/t7'); {Инициализация графики}

SetColor (White);

SetLineStyle (SolidLn, 0, NormWidth);

SetFillStyle (SolidFill, Red);

Sector (100, 200, 45, 135, 80, 80);

{Закрашенный красным цветом сектор с центром (100, 200),

начальным углом 45, конечным углом 135 и радиусом 80}

SetColor (Red);

SetLineStyle (SolidLn, 0, ThickWidth);

SetFillStyle (SolidFill, Yellow);

Rectangle (300, 10, 400, 70);

FloodFill (350, 50, Red);

{Рисование прямоугольника сплошной толстой красной линией, закрашенного желтым цветом}

SetColor (Cayan);

SetLineStyle (SolidLn, 0, NormWidth);

SetFillStyle (7, Red);

Cercle (500, 250, 50);

FloodFill (500, 250, Cayan);

{Рисование круга голубой линией стандартной толщины, закрашенного сетчатой штриховкой красного цвета}

Readln;

CloseGRAPH

end.

Вывод текста. Выводимые на экран изображения обычно сопровождаются пояснительным текстом. В графических режимах для этого используются процедуры OutText и OutTextXY. Процедура OutText (Text) выводит строку текста, начиная с текущего положения Cp. Процедура OutTextXY (X, Y, Text), где X, Y - координаты точки начала вывода текста (левый верхний угол выводимого текста), Text - константа или переменная типа string.

Качественное оформление самого текста требует при его выводе использования самых различных шрифтов. Установить нужный шрифт можно процедурой: SetTextStyle (Font: word; Direction: word; CharSize: word), где Font - выбранный шрифт, Direction – направление (горизонтальное - Direction = 0, вертикальное - Direction = 1), СharSize - размер выводимых символов. Система TurboPascal имеет свои собственные шрифты, отличные от классических текстовых редакторов. Шрифты вывода текста в графике Паскаля представлены в таб. 5

.Таб. 5. Таблица шрифтов

Константа Значение Описание
DefaultFont TriplexFont SmaillFont SanSerifFont GothicFont 8*8 битовый шрифт Штриховые шрифты Малый шрифт Сансериф Готический

Нужную величину шрифта можно установить еще одним способом - с помощью процедуры SetUserCharSize (multX, divX, multY, divY: word). Первые два параметра управляют горизонтальным размером, два последних - вертикальным. Если взять за 1 ширину стандартного шрифта, то отношение multX/divX будет устанавливать ширину.

В данной таблице даны шрифты размером 0 и имеющие горизонтальную ориентацию.

Приведем пример программы, которая демонстрирует применение различных шрифтов и их размеров при выводе текста.

Uses GRAPH;

Var i, d: integer;

begin

d := detect;

InitGRAPH (d, i, 'G/Work/t7'); {Инициализация графики}

{Горизонтальный текст}

SetColor (Blue);

SetTextStyle (DefaultFont, HorizDir, 3);

OutTextXY (5, 1, ‘DefaultFont размером 3’); {Шрифт Default синего цвета}

SetColor (Red);

SetTextStyle (TriplexFont, HorizDir, 1);

OutTextXY (5, 3, ‘TriplexFont размером 1’); {Шрифт Triplex красного цвета}

SetColor (Yellow);

SetTextStyle (SmaillFont, 0, 4);

OutTextXY (5, 5, ‘SmaillFont размером 4’); {Шрифт Smaill желтого цвета}

{Вертикальный текст}

SetColor (Green);

SetTextStyle (DefaultFont, VertDir, 3);

OutTextXY (20, 7, ‘DefaultFont размером 3’); {Шрифт Default зеленого цвета}

SetColor (Blue);

SetTextStyle (TriplexFont, 1, 1);

OutTextXY (5, 3, ‘TriplexFont размером 1’); {Шрифт Triplex синего цвета}

SetColor (Yellow);

SetTextStyle (GothicFont, VertDir, 2);

OutTextXY (5, 5, ‘GothicFont размером 2’); {Шрифт Smaill желтого цвета}

Readln;

CloseGRAPH

end.

Средства работы с фрагментами. Эффект движения в графическом режиме. В дополнение к уже рассмотренным ранее графическим средствам построения и вывода изображений имеется еще ряд дополнительных процедур, позволяющих сохранять и восстанавливать отдельные фрагменты изображения. Для манипулирования фрагментом надо в первую очередь узнать его размер. Это делается с помощью функции ImageSize (X1, Y1, X2, Y2), где X1, Y1, X2, Y2 - координаты верхнего левого и правого нижнего угла прямоугольной области экрана. Функция возвращает размер указанного фрагмента в байтах. Затем в памяти машины выделяется место под фрагмент. Для этого пользуются процедурой GetMem (BitMap, Size), где BitMap - переменная типа pointer, Size - размер фрагмента, полученный с помощью ImageSize.

Сохранение образа фрагмента в памяти выполняется процедурой GetImage (X1, Y1, X2, Y2, BitMap), где X1, Y1, X2, Y2 - координаты фрагмента, BitMap – нетипизированная ссылка. Возвратить образ фрагмента из памяти на экран можно с помощью процедуры PutImage (X, Y, BitMap, Mode), где X, Y - координаты точки экрана, начиная с которой будет выводиться фрагмент, BitMap - уже упомянутая нетипизированная константа, которая задает высоту и ширину фрагмента. Параметр Mode определяет, какой двоичный оператор будет использоваться для вывода двоичного образа области на экран. Например, PutImage(X, Y, BitMap, NormalPut).

Описанными выше процедурами можно пользоваться для создания на дисплее каких-либо движущихся объектов. Ниже приведена подобная программа.

Uses Crt, GRAPH;

Var i, d, Size: integer; p: pointer;

begin

d := detect;

InitGRAPH (d, i, 'G/Work/t7'); {Инициализация графики}

SetColor (Red);

Circle (30, 232, 10); {Рисование окружности красного цвета}

SetFillStyle (1, Red);

FloodFill (30, 232, Red); {Закраска круга красным цветом}

Size := ImageSize (18, 220, 42, 244); {«Измерение» круга}

GetMem (р, Size); {Выделение в памяти места для круга}

GetImage (18, 220, 42, 244, р^); {Запись в память двоичного кода круга}

While not KeyPressed do

begin

Fori:=18 to 600 do {Плавное перемещение круга слева направо}

PutImage (i, 220, р^, NormalPut);

For i:= 600 downto 18 do {Плавное перемещение круга справа налево}

PutImage (i, 220, р^, NormalPut);

end;

end.

Эта программа реализует перемещение красного шарика от левого края экрана до правого и обратно. Процесс прекращается по нажатию любой клавиши.

Лабораторная работа №7

Цель работы: освоить графические процедуры и функции; научиться создавать программы построения на экране различных изображений, заполнять их цветом; освоить технологию вывода на экран текста в графическом режиме; организовывать движение графических объектов по монитору.

Основные теоретические положения.

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

Перед выполнением работы необходимо ознакомиться с теоретическим материалом по теме «Программирование графики».

Пример 1. Составить программу построения узора, образованного пересечением двух семейств расходящихся отрезков, у которых k1 и k2 - расстояния между отрезками слева и справа, а h – смещение-наклон вниз (вверх) всего семейства.

Решение. Построение горизонтальной линии осуществляется процедурой line (0, k, 640, k). Если нужно построить n линий, то эту процедуру надо поместить в цикл: for i:=1 to n do line (0, i*k, 640, i*k). Наклон линий получается добавлением шага h ко второй координате (h>0, то наклон вниз, h<0, то наклон вверх): for i:=1 to n do line (0, i*k, 640, i*k+h). Расширение и сужение прямых путем задания различных значений k1 и k2 величины k: for i:=1 to n do line (0, i*k1, 640, i*k2+h). Второе семейство получается, если наклон линий производить по первой координате: for i:=1 to n do line (0, i*k2+h, 640, i*k1).

Uses crt, graf;

Var gD, gM, i, k1, k2, h: integer;

Begin

k1:= 8; k2 := 3; h:=110; gD:= Detect;

InutGraf (gD, gM, ‘’); setcolor(red);

For i:= 1 to (480 div k1) do

Begin

for i :=1 to n do line (0, i*k1, 640, i*k2+h):

for i :=1 to n do line (0, i*k2+h, 640, i*k1);

end;

readln; Closegraph

end.

Пример 2. Построить график функции y = x2 на отрезке [a, b].

Решение. Для построения графика функции нужно разбить отрезок [a, b] на n частей (h – шаг разбиения (b-a)/n), а затем проводить с помощью процедур line и lineto отрезки прямой, который и образуют ломаную линию графика функции. Можно, конечно воспользоваться и выводом точки (точечное построение графика). В программе построим функцию вычисления ее значений в произвольной точке и процедуру построения по точкам ломаной линии, представляющей собой график функции.

Uses crt, graf;

Var gD, gM, n: integer;

a, b: real;

function f (x: real) : real;

Begin

f:= x*x

End;

Procedure graf (x0, x1, y0, y1, n: word; a, b: real);

Var h, m, x, t1, t2 :real;

i, u, v, xv, yv: word;

begin

h:= (b-a)/n; {Нахождение шага разбиения}

m:= abs(f(a)); {Поиск значения функции в левом конце отрезка}

t1:= (x1-x0) / (b-a); t2:= (y1-y0) / (2*m);

{Построение координатных осей}

setfillstyle (1,15); bar( x0-5, y0-5, x1+5, y1+5);

xv:= round(x0-a*t1); yv:= round((t0+y1) / 2);

line (x0, yv, x1, yv);

{Установка текущего курсора в начало графика}

Moveto (x0, yv-round (f (a)*t2);

{Построение тграфика}

Setcolor (3);

For i:= 1 to n do

Begin

x:= a+i*h; u:= x0+round ( (x-a)*t1);

v:= yv:= round (f (x)*t2); lineto (u, v);

end;

end; {Конец процедуры}

begin

clrscr; readln (a, b, n); gD:= Detect;

Initgraph (gD, gM, ‘’);

graf (100, 500, 50, 300, n, a, b);

Readln; Closegraph

end.

Пример 3. Вращение Земли вокруг Солнца.

Решение. Организуем движение точки (Земли) по окружности, в центре которой размещается круг (Солнце). Установку точки на орбите можно осуществить по параметрическим формулам окружности:

X0 := 320 + r*sin(A);

Y0 := 240 + r*cos(A),

где r1 – радиус орбиты Земли, А - параметрический угол, меняющийся от 0 до 360 градусов. Чтобы организовать движение, достаточно в цикле устанавливать точку с координатами (x0, y0) для всех углов, принимающих значение от 0 до 360 градусов с шагом h.

Uses Crt, GRAPH;

Var i, d: integer;

fi, h, ; real;

x0, y0, r1: integer;

begin

d := detect;

InitGRAPH (d, i, 'G/Work/t7'); {Инициализация графики}

SetColor (Red);

Circle (320, 240, 10); {Рисование окружности красного цвета}

SetFillStyle (1, Red);

FloodFill (320, 240, Red); {Закраска круга (Солнца) красным цветом}

R1:= 100; h:=5; fi:= 0;

Repeat

X0:= round (r1*sin (fi)) +320;

Y0:= round (r1*cos(fi)) +240;

fi:= fi+2*pi*h/360;

Putpixel (x0, y0, 15);

delay(50);

Putpixel ((x0, y0, 0);

Until keypressed;

CloseGraph

end.

Варианты заданий

Задание 1. Составить программу моделирования паркетов из:

a) прямоугольных треугольников;

e) равносторонних треугольников;

f) ромбов;

g) трапеций;

Задание 2. Разработайте программу для построения следующих графиков функций:

a) y = x3 ;

b) y= ex ;

c) y = ln (x);

d) y = sqrt (x)).

Задание 3. Разработайте динамическую модель:

a) Солнца для двух планет;

b) Солнца для Земли и Луны;

c) столкновение двух ядер;

d) старт ракеты.

Содержание отчета

1. Постановка задачи.

2. Описание алгоритма.

3. Тестовые примеры и анализ результатов тестирования.

4. Вывод.

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

1. Какой процедурой выполняется установка типа линий?

2. Как построить ломаную линию?

3. Какой процедурой выполняется установка типа закраски?

4. Какой процедурой выполняется установка шрифта для вывода текста?

5. Какой процедурой можно вывести на экран изображение куба?

6. Как нарисовать кольцо указанного цвета?

7. Можно ли процедурой Ellipse вывести на экран окружность?

8. Каким образом строятся сектора (круговые и эллиптические)?

9. Каким образом можно из рисунка выделить его фрагмент и вставить в другой рисунок?

10. С помощью каких процедур и функций осуществляется эффект движения изображения по экрану?

Литература

1. Касторнов А. Ф. Методическое пособие по курсу "Алгоритмический язык Паскаль". - Череповец, 1995.

2. Касторнова В. А., Касторнов А. Ф. Демонстрационно-обучающий курс “Алгоритмический язык Паскаль”. // Информатика и образование. - 1998. - №2.-С.48-61.

3. Немнюгин С. А. Turbo Pascal: Программирование на языке высокого уровня: Учебник для вузов. – СПб.: Питер, 2007.

4. Павловская Т. А. Паскаль. Программирование на языке высокого уровня: Учебник для вузов. – СПб.: Питер, 2004.

5. Павловская Т. А. Паскаль. Программирование на языке высокого уровня: Практикум. – СПб.: Питер, 2006.

6. Ставровский А. Б. Турбо Паскаль 7.0: Учебник для вузов. – Киев, 2001.

7. Фаронов В. В. Система программирования Delphi. – СПб., 2006.

8. Фаронов В. В. Турбо Паскаль 7.0: Практика программирования: учебное пособие.-М.: ОМД Групп, 2003.

9. Программирование на языке Паскаль: задачник / под ред. Усковой О. Ф. – СПб.: Питер, 2002.

10. Юркин А. Г. Задачник по программированию. – СПб.: Питер, 2002.


Наши рекомендации