Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







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





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

 

 

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

 

 







ЧТО И КАК ПИСАЛИ О МОДЕ В ЖУРНАЛАХ НАЧАЛА XX ВЕКА Первый номер журнала «Аполлон» за 1909 г. начинался, по сути, с программного заявления редакции журнала...

Живите по правилу: МАЛО ЛИ ЧТО НА СВЕТЕ СУЩЕСТВУЕТ? Я неслучайно подчеркиваю, что место в голове ограничено, а информации вокруг много, и что ваше право...

ЧТО ПРОИСХОДИТ ВО ВЗРОСЛОЙ ЖИЗНИ? Если вы все еще «неправильно» связаны с матерью, вы избегаете отделения и независимого взрослого существования...

Что делать, если нет взаимности? А теперь спустимся с небес на землю. Приземлились? Продолжаем разговор...





Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2024 zdamsam.ru Размещенные материалы защищены законодательством РФ.