Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Рисование геометрических фигур



Построение заполненных фигур

 

 

Ряд графических процедур выполняет построение заполненных фигур - фигур с замкнутым контуром, автоматически заполняемых сразу после построения. По умолчанию заполнение производится сплошным белым цветом. Цвет и стиль (орнамент) заполнения можно устанавливать из стандартного набора BGI или определять самим.

 
 


SetFillStyle(P, N); - процедура установки орнамента P=0, 1, ..., 12 и

цвета с номером " N" для заполняемых фигур.

 

P = 0 - сплошное заполнение цветом фона, при этом значение " N" игнорируется,

P = 1 - сплошное заполнение цветом с номером " N",

P = 2... 11 - стандартный набор орнаментов BGI,

P = 12 - орнамент и цвет определяет пользователь.

 
 


SetFillPattern(PP, N); - процедура установки орнамента пользователя PP

и цвета с номером " N" для заполняемых фигур.

 

Параметр PP имеет тип FillPatternType или array [1.. 8] of byte. Байт состоит из восьми битов и соответствует ряду из 8 пикселов, т. е. параметр РР определяет элемент орнамента размером 8*8 пикселов (восемь рядов по восемь пикселов). Если бит равен 1, то пиксел высвечивается заданным цветом, если бит равен 0 - текущим цветом фона.

 

Пример орнамента в виде буквы Y:

 
 


№ элемент двоичные шестнадцатеричные

Байта орнамента числа числа

       
 
 
   


1 1 0 0 0 0 0 0 1 $81

2 1 1 0 0 0 0 1 1 $C3

3 0 1 1 0 0 1 1 0 $66

4 0 0 1 1 1 1 0 0 $3C

5 0 0 0 1 1 0 0 0 $18

6 0 0 0 1 1 0 0 0 $18

7 0 0 0 1 1 0 0 0 $18

8 0 0 0 1 1 0 0 0 $18

Шестнадцатеричные цифры соответствуют двоичным тетрадам цифр:

 

0000 - 0 0100 - 4 1000 - 8 1100 - С

0001 - 1 0101 - 5 1001 - 9 1101 - D

0010 - 2 0110 - 6 1010 - A 1110 - E

0011 - 3 0111 - 7 1011 - B 1111 - F

 

Причем, двоичное число разбивается на тетрады цифр с конца числа, а шестнадцатеричное число получается заменой каждой тетрады соответствующей цифрой с добавлением в начале числа символа " $".

 

Орнамент удобно задавать, используя переменные с начальным значением (типизированные константы), например:

{оператор описания: }

Const Bukva_Y: FillPatternType=($81, $C3, $66, $3C, $18, $18, $18, $18 );

 

{оператор выполнения: } SetFillPattern(Bukva_Y, 4);

 

Можно добавлять один орнамент к другому используя логические операции, например, A и B - исходные орнаменты, Z - результирующий орнамент. Тогда:

Z: = A and B; - орнамент из совпадающих единичных частей исходных орнаментов,

Z: = A or B; - орнамент с добавлением единичных частей исходных орнаментов,

Z: = A xor B; - орнамент из несовпадающих единичных частей исходных орнаментов,

Z: = not A; - орнамент инверсный (обратный) к исходному орнаменту.

Z: = A xor A; - обнуление, Z: = A xor (not A); - сплошное заполнение орнамента.

 

Приведем процедуры построения заполненных установленным орнаментом фигур. Граница заполняемых фигур рисуется текущим цветом для линий.

 
 


Bar(X1, Y1, X2, Y2); - построить заполненный прямоугольник с заданными

координатами левого верхнего (X1, Y1) и правого

нижнего (X2, Y2) углов. Аналог процедуры: Rectangle(X1, Y1, X2, Y2);.

 
 


Bar3d(X1, Y1, X2, Y2, d, t); -построить параллелепипед с заполненной

передней гранью. Координаты углов: (X1, Y1), (X2, Y2), глубина " d". Переменная " t" типа boolean задает вывод верхней грани. При t=TopOn (true) верхняя грань показывается, при t=TopOff (false) - нет.

 
 


FillEllipse(X, Y, RX, RY); - построить заполненный эллипс с центром в

точке (X, Y) и радиусами ( полуосями ):

RX - по горизонтали, RY - по вертикали.

Sector(X, Y, A1, A2, RX, RY); - построить заполненный сектор эллипса.

A1 и A2 - начальный и конечный углы (в градусах), отсчитываемые против часовой стрелки относительно направления оси Х. Аналог процедуры: Ellipse(X, Y, A1, A2, RX, RY); строит сектор эллипса без автоматического заполнения.

 
 


PieSlice(X, Y, A1, A2, R); - построить заполненный сектор круга с

центром в точке (X, Y) и радиусом R. Аналог процедуры: Arc(X, Y, A1, A2, R); строит дугу окружности.

 
 


FillPoly(N, M); - заполнить произвольную плоскую фигуру с границей,

описанной массивом точек. N - число точек границы,

М - параметр - переменная типа PointType, определяемая в модуле Graph в виде:

TYPE PointType = Record x, y: Integer End; В программе массив можно описать операторами: Const N=100; Var M: array[1..N] of PointType;

Присвоение значений можно провести в цикле:

For i: =1 to 3 do begin M[i].x: =random(95); M[i].y: =random(95) end;

Приведем пример программы, выводящей два прямоугольника с орнаментами пользователя (bukva_Y и Red_50), а затем демонстрирующей набор стандартных орнаментов на передней грани параллелепипедов:

 

Uses Graph; Сonst

bukva_Y: FillPatternType=($81, $C3, $66, $3C, $18, $18, $18, $18);

Red_50: FillPatternType=($AA, $55, $AA, $55, $AA, $55, $AA, $55);

var i, x1, y1, x2, y2, Gd, Gm: integer;

Begin Gd: = Detect; InitGraph(Gd, Gm, '_');

SetFillPattern(Red_50, Red); { орнамент - 50% красных пикселов }

Bar(250, 10, 350, 110);

SetFillPattern(bukva_Y, Blue); { орнамент - синяя буква " Y" }

Bar(340, 30, 440, 130);

{ стандартный набор из 12 орнаментов BGI выводим цветом с номером " 11" }

for i: =0 to 11 do begin SetFillStyle(i, 11);

if i< 6 then begin x1: =90*i; y1: =150 end

else begin x1: =90*(i-6); y1: =270 end;

x2: =x1+70; y2: =y1+80;

Bar3d(x1, y1, x2, y2, 10, TopOn) end;

ReadLn; CloseGraph

End.

Заполняя не черный экран орнаментом Red_50, можно получить новые цвета фона.

Выбранным из стандартных или определенным орнаментом можно заполнить любую замкнутую область с границей цвета " N" оператором

 
 


FloodFill(X, Y, N);

 

Заполнение начинает производится из точки X, Y и ограничивается при достижении границы цвета с номером " N". Например: Rectangle(x1, y1, x2, y2); FloodFill((x1+x2) div 2, (y1+y2) div 2, Red); Если область не замкнута или цвет границы не равен " N", то заполнение " разольется" по экрану.

 

Практическое задание N 1. 54

 

1. С использованием оператора цикла нарисовать на экране 12 одинаковых заполненных различными стандартными орнаментами фигур ( в 3 ряда по 4 фигуры). По нажатию клавиши должен меняться вариант фигуры:

1. 1 Прямоугольник, 2. 1 Эллипс,

1. 2 Параллелепипед. 2. 2 Круг.

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

2. Нарисовать 5 вложенных прямоугольников с увеличением размера на 20 пикселов в каждом направлении. Стиль заполнения для каждой фигуры определить буквами Вашего имени.

3. Нарисовать 5 соосных кругов разного цвета с уменьшением радиуса на 10 пикселов. Стиль заполнения для каждого круга определить его номером, т. е. цифрами 1, 2, 3, 4, 5.

4. Определить три орнамента заполнения: " снежинка", " иголки" с наклоном влево и вправо. Нарисовать из треугольников пять елок и заполнить их орнаментом " иголки". Заполнить экран орнаментом " снежинка".

5. Создать элемент орнамента с единицами (4*4) в центре. Нарисовать на экране картину " ночной город", используя фрагменты " звездного неба" и пять прямоугольников, заполненных орнаментом 4*4 разного цвета.

6. Используя исходные орнаменты из одной линии составить с использованием логических операций орнаменты цифр: 1, 6, 7 и букв: B, F, E.

 

Работа с линиями

 

 

В графическом режиме курсор невидим, его положение можно определить функциями, возвращающими значения координат:

       
   


GetX; - по оси " Х", GetY; - по оси " Y".

 

 

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

 
 


MoveTo(x, y); - переместить курсор в точку с координатами (x, y),

MoveRel(dx, dy); - сместить курсор на расстояние dx, dy от текущего положения.

 

 

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

 
 


LineTo(x, y); - провести отрезок прямой линии от текущего положения

курсора до точки с координатами X, Y.

LineRel(dX, dY); - провести отрезок прямой линии от текущего положения

курсора до точки, смещенной на расстояние dX, dY по

соответствующим осям.

В отличие от процедуры Line(x1, y1, x2, y2); процедуры LineTo(x, y); и LineRel(dX, dY); при своем исполнении перемещают текущий указатель.


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

 
 


R: =100; { расстояние от вершин до центра xc, yc }

xc: = GetMaxX div 2; yc: = GetMaxY div 2;

for i: = 1 to 8 do begin alfa: = i * pi/4; { значение угла в рад. }

x[i]: = xc + round(R * cos(alfa)); { координаты вершин }

y[i]: = yc + round(R * sin(alfa))

end;

MoveTo(x[8], y[8]); { исходная позиция для рисования }

for i: = 1 to 8 do LineTo(x[i], y[i]); { рисование линий }

 

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

 
 


SetWriteMode(N);

 

N=0 - замещение линией изображения на экране ( режим CopyPut ) используется по умолчанию,

N=1 - изображение комбинируется ( режим XorPut ). Работа функции состоит в изменении согласно логической операции " исключающее ИЛИ" исходного значения цвета пиксела (числа " 1" или " 0" ). Логическая функция Xor, примененная к одной переменной дважды, восстанавливает ее исходное значение: ( J xor I ) xor I = J. Следовательно при повторном проведении линии в режиме XorPut изображение этой линии уничтожается, а цвет пикселов экрана становится исходным. На этом правиле основаны некоторые программы построения движущихся изображений.

 

 

Пример операторов для рисования движущегося прямоугольника:

SetWriteMode(1);

a: = 100; b: = 50; { стороны прямоугольника }

x1: = 0; y1: = GetMaxY div 2;

N: = GetMaxX - x1 - a; { N - число перемещений }

for i: = 0 to N do begin

Rectangle(x1+i, y1, x1+a+i, y1+b); { рисование прямоугольника }

delay(10); Rectangle(x1+i, y1, x1+a+i, y1+b); { стирание прямоугольника }

end;

 

Практическое задание N 1. 55

 

1. Составить процедуру рисования N - угольной звезды. В параметры процедуры включить число лучей звезды, радиусы вписанной и описанной окружностей, цвет линий и координаты центра звезды. Перемещать две звезды разного цвета в пределах экрана случайным образом.

 

2. Составить процедуру рисования N - угольной звезды,

где N= 3, 5, 7, ... Операторы рисования имеют вид:

M: =N div 2; Moveto(x[1], y[1]);

For i: =1 to N do begin j: =(M*i) mod N + 1;

LineTo(x[j], y[j]) end;

Перемещать две звезды разного цвета в пределах экрана.

Толщину и форму (стиль) линий отрезков прямых, прямоугольников, окружностей, эллипсов можно задать оператором

 
 


SetLineStyle(F, P, T);

 

Здесь F - форма линии из стандартного набора BGI:

F=0 - сплошная,

F=1 - пунктирная,

F=2 - штрих-пунктирная,

F=3 - штриховая.

F=4 - форма линии задается параметром Р. При F< 4 значение Р игнорируется. Параметры F, P, T типа Word.

Стиль линии Р - число, двоичное представление которого отображает заполнение линии длиной 16 пикселов. Если разряд числа равен 1, то пиксел высвечивается, 0 - не высвечивается. Удобно использовать шестнадцатеричные числа. Например:

P = $35F1 = 0 0 1 1 0 1 0 1 1 1 1 1 0 0 0 1 ( двоичное )

отобразит стиль:

 

Можно использовать десятичную форму записи значения параметра " Р",

где 0< = P < = 65535= 216-1.

T - толщина линии может принимать два значения:

T= 1 - тонкая (1 пиксел), T= 3 - толстая (3 пиксела).

Например, операторы: SetLineStyle(4, $5555, 3); Line(x1, y1, x2, y2); определяют толстую мелким пунктиром линию.

 

 

Практическое задание N 1. 55

 

1. Вывести на экран горизонтальные толстые линии с двоичным представлением:

 

1111000001100000, 1111000011110000, 0111101111011110,

1100110011001100, 1001100110011001, 1111100011111000.

 

2. Вывести на экран вертикальные толстые линии с двоичным представлением:

 

0101010101010101, 1100011000110001, 1111110011111100,

0111011101110111, 1110001110001110, 1111000000001111.

 

3. Вывести на экран линии разных форм, заданных параметром РN = PN-1 + 2 * N,

где P0= 1; N= 1, .., 150. Линии располагать вертикально.

4. Вывода на экран линий разных форм, заданных параметром РN = PN-1 + 2N,

где P0= 1; N= 1, .., 15. Линии располагать горизонтально.

5. Нарисовать расходящийся из центра экрана по спирали ромбический лабиринт шириной 6 пикселов из отрезков наклонных прямых. Очищать экран и менять толщину и форму линии F= 0, .., 3.

6. Нарисовать расходящийся из центра экрана по спирали прямоугольный лабиринт шириной 5 пикселов из отрезков вертикальных и горизонтальных прямых. Очищать экран и менять толщину и форму линии.

 

 

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

 

P3 = P1 and P2 - линии из совпадающих единичных битов.

P3 = P1 or P2 - добавление единичных битов.

P3 = P1 xor P2 - обнуление совпадающих значений битов.

P3 = not P2 - изменение значений битов на противоположные.

Таблица результатов выполнения логической операции " xor" над битами.

 

( Таблица результатов выполнения

бит " A" операция бит " B" результат логических операций " or" и " and"

над битами приведена на стр.. )

Xor 1 0

1 xor 0 1 Результат операции " A xor B" равен

0 xor 0 0 единице при различных значениях битов

0 xor 1 1 " A" и " B", иначе результат равен нулю.

 

 

Практическое задание N 1. 56

 

1. Создать эффект " бегущих огней" перемещением на один пиксел набора из трех касающихся толстых пунктирных линий ( перерисовка в режиме XorPut ). Крайние линии стиля " Р", средняя - стиля " not P".

2. Создать штриховые стили " Р1", " Р2" и рассчитать с использованием всех логические операций приведенные выше стили Р3. Вывести на экран исходные и расчетные линии.

 

 

Создание графических узоров

 

 

Графические узоры создают для декоративных заставок, рекламы, демонстрации возможностей аппаратуры. Как правило, компьютерные узоры выполняются по весьма простым алгоритмам. Главное - идея создания декоративного эффекта.

Рассмотрим некоторые из принципов составления узоров на плоскости:

 

Перемещение фигуры.

Если фигуру перемещать не вращая относительно своего " центра", то получим плоскопараллельное движение тела (любой отрезок прямой на фигуре остается параллельным самому себе). За " центр" фигуры может быть принята любая точка жестко связанная с фигурой. Обычно " центр" фигуры (xf, yf) перемещают относительно центра узора (xc, yc) по определенному закону:

 
 


xc Fx xf X

yc xf = xc + Fx(" параметры" ),

Fy yf = yc + Fy(" параметры" ),

 

yf где Fx, Fy - функции от параметров.

Y Y

 

Приведем пример задания закона движения " центра" фигуры относительно центра узора:

for i: = 1 to Nc do begin

alfa: =2 * pi * i/Nc; { угол поворота " центра" фигуры }

Lx: = FLx(i); Ly: = FLy(i); { функции расстояний }

R: = FR(i); S: = FS(i); { функции радиуса и цвета окружности }

xf: = xc + round(Lx * cos(alfa)); { координаты " центра" фигуры }

yf: = yc + round(Ly * sin(alfa));

SetColor(S); Circle(xf, yf, R) end;

В этом фрагменте Nc - раз рисуется окружность с центром, поворачивающимся на угол alfa вокруг центра узора. Расстояние от центра i-й окружности до центра узора задается функциями Flx( i ), Fly( i ), радиус окружности - функцией FR( i ), цвет - функцией FS( i ). Подбором этих функций и числа окружностей Nc можно добиться разнообразных декоративных эффектов. Вместо окружностей можно строить любые фигуры, используя процедуры их рисования с заданием " центра" фигуры и других параметров в системе координат экрана.

В общем случае фигура может перемещаться вращаясь относительно своего " центра" и деформироваться. При этом параметры процедуры рисования фигуры должны включать все координаты точек, которые соединяются линиями. Координаты i-ой точки фигуры определяются по формулам:

 

xxi = xf + Kxi * ((xi-xf) * cos(A) - (yi-yf) * sin(A)),

yyi = yf + Kyi * ((yi-yf) * cos(A) + (xi-xf) * sin(A)),

где A - угол поворота фигуры относительно своего " центра", отсчитываемый в левой системе координат экрана по часовой стрелке относительно оси X,

xi, yi - исходные координаты i -ой точки фигуры,

xxi, yyi - новые координаты i -ой точки фигуры,

Kхi, Kyi - коэффициенты масштабирования координат i -ой точки по осям Х и Y.

 

 

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

 

for j: = 1 to Nf do begin

A: = 2 * pi * j/Nf; { угол поворота линии вокруг своего " центра" }

Kx1: = FKx1(j); Ky1: = FKy1(j); Kx2: = FKx2(j); Ky2: = FKy2(j);

{ координаты 1-ой точки фигуры }

xx1: = xf + round(Kx1 * ((x1-xf)*cos(A) - (y1-yf)*sin(A)));

yy1: = yf + round(Ky1 * ((y1-yf)*cos(A) + (x1-xf)*sin(A)));

{ координаты 2-ой точки фигуры }

xx2: = xf + round(Kx2* ((x2-xf)*cos(A) - (y2-yf)*sin(A)));

yy2: = yf + round(Ky2* ((y2-yf)*cos(A) + (x2-xf)*sin(A)));

 

SetColor(14); line(xx1, yy1, xx2, yy2); delay(100);

end;

 

x1, y1, x2, y2 - исходные координаты точек фигуры,

xx1, yy1, xx2, yy2 - координаты 1-ой и 2-ой точек фигуры на i-ом шаге рисования.

В этом фрагменте многократно (Nf - раз) рисуется линия, вращающаяся на угол " A” относительно своего центра xf, yf. Фигура может искажаться (деформироваться), если не соблюдаются равенства: Fkx1( j)= Fky1( j)= Fkx2( j)= Fky2( j)= K= 1.

Если центр узора перемещается, то изменение его координат необходимо задать во внешнем цикле.

 

Практическое задание N 1. 56

 

1. Нарисовать узор из 30 - ти эллипсов с центром узора в середине экрана. Радиусы каждого эллипса (Rx, Ry) и расстояние от " центра" эллипсов до центра узора увеличивать на один пиксел.

2. Нарисовать узор из 20 -ти прямоугольников с центром узора в середине экрана. Длины сторон прямоугольников и расстояние от центра узора до " центра" фигуры (например, левого верхнего угла прямоугольника) уменьшать на один пиксел. Для рисования прямоугольника использовать оператор: Rectangle(xf, yf, xf+a-i, yf+b-i); где a и b - стороны прямоугольника, i - параметр цикла вращения вокруг центра узора.

3. Нарисовать узор из отрезка прямой линии, вращающегося вокруг своего " центра" (N - раз) за один оборот вокруг центра узора.

4. Нарисовать узор из отрезка прямой линии, вращающегося вокруг своего " центра" (N - раз) за один полупериод движения по синусоиде.

yf = yс + Af * sin((xf-xc)/100), где Xf = xc + 10 * Pi * j; j= 1, 2, .., 10,

Af - задать исходя из размеров экрана.

5. Составить процедуру рисования самолета (задавать координаты узлов, которые соединяются прямыми линиями). Нарисовать самолет, движущийся вокруг центра узора по эллиптической траектории (Lx< > Ly). Самолет должен поворачиваться вокруг своего " центра" в соответствии с траекторией ( cos(A)= Fx/L, sin(A)= Fy/L, где L= /Fx2 + Fy2 ).

6. Составить процедуру рисования машины (задавать координаты узлов, которые соединяются прямыми линиями). Нарисовать машину, движущуюся синусоиде. Машина должна поворачиваться вокруг своего " центра" в соответствии с траекторией ( A= arctg(d(yf)/d(xf)), для данного случая: A: =arctan(Af/100*cos((xf-xc)/100);

 

Примечание к п. 5, 6: Фигура перерисовывается в режиме SetWriteMode(1);

 

Масштабирование фигуры.

Рассмотрим случай уменьшения размеров фигуры делением ее сторон.

 

N: = 7; R: = 170; xc: = GetMaxX div 2; yc: = GetMaxY div 2;

for i: = 1 to N do begin alfa: = i*2. *pi/N;

x[i]: = xc + round(R*cos(alfa)); { координаты вершин }

y[i]: = yc + round(R*sin(alfa)) { исходного N-угольника }

end;

MoveTo(x[N], y[N]);

for i: = 1 to N do LineTo(x[i], y[i]); { рисуем N-угольник }

ch: = ReadKey; { нажать клавишу }

Repeat { найдем середины сторон многоугольника

и запишем их в массивы новых координат многоугольника }

x1: = x[1]; y1: = y[1];

for i: =1 to N-1 do begin x[i]: = (x[i]+x[i+1]) div 2;

y[i]: = (y[i]+y[i+1]) div 2 end;

x[N]: = (x[N]+x1) div 2;

y[N]: = (y[N]+y1) div 2;

{ строим многоугольник по новым точкам }

MoveTo(x[N], y[N]);

for i: =1 to N do LineTo(x[i], y[i]);

ch: =ReadKey; { нажать клавишу }

Until ch=#27;

 
 


При нажатии клавиши внутрь фигуры будет " убегать" ее уменьшенная копия до нажатия клавиши Esc. Стороны можно делить не пополам, а в каком-либо соотношении. Для стирания фигуры необходимо перерисовать ее в режиме XorPut.

Масштабирование фигур можно проводить используя зависимости, приведенные выше для вращения фигуры относительно своего " центра", изменяя Kx и Ky, при постоянных параметрах xf, yf, A.

 

Практическое задание N 1. 57

 

1. Создать уменьшающийся треугольник (деление сторон 9: 1) и пульсирующий треугольник.

2. Создать уменьшающийся прямоугольник (деление сторон 3: 1) и пульсирующий прямоугольник.

Примечание к п. 1 и п. 2: пульсация фигуры достигается перерисовкой ее в режиме XorPut, при многократном увеличении и последующем уменьшении коэффициента масштабирования, например, по закону: K= K + i*0. 02. Где i - параметр цикла.

 

 


Поделиться:



Последнее изменение этой страницы: 2017-03-17; Просмотров: 565; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.156 с.)
Главная | Случайная страница | Обратная связь