
- •Часть 2
- •Содержание
- •1 Цель работы
- •2 Построение многоугольников.
- •3 Практическое задание
- •4 Построение сложных линейчатых фигур
- •5 Практическое задание
- •6 Стили и режимы вывода линейчатых фигур
- •7 Практическое задание
- •1 Цель работы
- •2 Многократное рисование фигуры с поворотом относительно центра узора
- •3 Практическое задание
- •4 Создание узоров построением зеркальных отображений.
- •5 Практическое задание
- •6 Масштабирование вписыванием фигур
- •7 Практическое задание
- •8 Штриховка углов
- •9 Практическое задание
- •1 Цель работы
- •2 Наборы последовательно выводимых отрезков с изменением их ориентации
- •3 Практическое задание
- •4 Разветвляющиеся наборы отрезков
- •5 Практическое задание
- •6 Лабиринты Гильберта
- •5 Практическое задание
- •1 Цель работы
- •2 Алгоритмы Брезенхейма
- •3 Практическое задание
- •4 Построение кривых второго порядка
- •3 Практическое задание
- •Часть 2
3 Практическое задание
3.1 Модернизировать процедуру построения окружности,
задав разные цвета по ее секторам.
3.2 Составить процедуру рисования отрезков с чередованием
цвета составляющих их пикселов.
3.3 Модернизировать алгоритм Брезенхейма, организовав
построение 4-связных отрезков прямых. Проконтролировать работу этого алгоритма на крупной сетке.
4 Построение кривых второго порядка
При построении сложных кривых наиболее простой метод - вычисление точных координат этой кривой, округление их до целых величин и вывод точек с получаемыми координатами. При этом необходимо, чтобы последовательно получаемые точки были связными. Приведем пример процедур рисования кривых второго порядка с использованием их представления в полярных координатах
, где p - параметр; e - эксцентриситет;
alf - угол для радиус-вектора R, конец
которого определяет множество точек
кривой. Полюс находится в фокусе кривой,
а полярная ось направлена от фокуса к
ближайшей вершине. При 0<=e<1 получаем
эллипс,
при e=1 - параболу, при e>1 - гиперболу.
Для построения непрерывной кривой из множества точек используется процедура _TRACE, в которой для получения очередной точки кривой первоначально полярный угол от предшествующей точки увеличивается на 1/R - для получения перпендикулярного радиусу смещения единичной длины. Если условие связности очередной и предшествующей точек не выполняется, то приращение угла уменьшается.
Кривые ограничиваются либо диапазоном изменения полярного угла, либо величиной полярного радиуса.
{----------------------------------------------------------}
PROCEDURE _TRACE( xf,yf, s, alf1,alf2, co,d: integer;
p,e,ug: real);
{ построение кривой второго порядка:
xf,yf
- координаты фокусаF;
s - размер (ограничение величины R
полярного радиуса);
alf1...alf2 - диапазон изменения alfось кривой
полярного угла; F
co - цвет; d - направление приращения полярного угла ( 1 - по часовой стрелке, -1 - против);p - фокальный параметр; e - эксцентриситет;ug - угол наклона оси симметрии кривой }
var r,alf,du,rot: real;
x,y, x_old,y_old: integer;
begin
{ полярный угол как параметр - начальное значение }
alf:= d*alf1*pi/180+ug;
r:= p/(1+e*cos(alf-ug)); { радиус-вектор из фокуса }
{ координаты первой точки - высчитываем и запоминаем }
x:=xf +round( r*cos(alf));
y:=yf +round( r*sin(alf));
x_old:=x; y_old:=y;
rot:=0; { счетчик угла поворота радиус-вектора }
REPEAT
{ определение очередной точки приращением полярного угла
начальное приближение обратно пропорционально радиусу }
du:=d/r;
Repeat
r:=p/(1+e*cos(alf-ug+du)); { радиус-вектор из фокуса }
x:=xf+round( r*cos(alf+du)); { координаты новой точки }
y:=yf+round( r*sin(alf+du));
If(abs( x-x_old)>1){ если очередная точка несвязна с предыдущей }
or(abs( y-y_old)>1)
then du:=du/2 { то уменьшаем приращение угла }
Until(abs(x-x_old)<=1)and(abs(y-y_old)<=1);
alf:=alf+du; { очередной угол обхода }
rot:=rot+abs(du); { расчет поворота радиус-вектора }
PutPixel( x,y,co); { очередная точка контура }
x_old:=x; y_old:=y { запоминаем координаты выведенной точки }
{ заканчиваем построение при полном проходе интервала по углу обхода или достижении нужного размера ( расстояния от точки кривой до фокуса ) }
UNTIL( rot>(alf2-alf1)*pi/180)or( r>s) end;
{----------------------------------------------------------}
PROCEDURE _ELLIPSE(xc,yc,ugol,r1,r2,alf1,alf2,co: integer);
{ xc,yc - центр эллипса,
ugol - наклон первой оси по горизонтали (град.),
r1,r2 - полуоси,
alf1...alf2 - диапазон изменения полярного угла,
со - цвет }
var r0: integer; f,p,e: real;
begin if( r1<=0)or( r2<=0) then exit;
{ если первая полуось меньше второй, то меняем оси
и их ориентацию на 90 градусов }
if( r1<r2) then begin r0:=r1; r1:=r2; r2:=r0;
ugol:=90-ugol end;
{ перевод в радианы с ориентацией против часовой стрелки }
ug:=-ugol*pi/180;
{ расстояние от фокуса до центра } R r2
f:=sqrt( abs(1.*r1*r1-r2*r2)); p r1
p:=r2*r2/r1; { фокальный параметр } F f (xc,yc)
e:=f/r1; { эксцентриситет }
{ координаты фокуса }
xf:=round( xc +f*cos(ug));
yf:=round( yc +f*sin(ug));
{ Вызов процедуры рисования без ограничения по R }
_TRACE(xf,yf, 3*r1, alf1,alf2, co,1, p,e,ug)
end;
{---------------------------------------------------------}
PROCEDURE _HIPERB(xc,yc, a, ugol,delta, s, alf1,alf2, co:
integer);
{ xc,yc - вершина гиперболы,a - расстояние до центра,
ugol - наклон оси, delta - угол между асимптотами (град.),
s - размер, alf1...alf2 - диапазон изменения полярного угла,
со - цвет }
var xf,yf: integer; b,c,f,p,e, ug,dlt: real;
begin
if( delta<=0)or( s<=0)
then exit;
{ перевод из градусов в радианы } R
dlt:=-delta*pi/180;
b:=a*sin(dlt/2)/cos(dlt/2); C c
{ расстояние от фокуса до центра } b F
c:=sqrt(1.*a*a +b*b); delta/2
f:=c-a; { от фокуса до вершины } a
p:=b*b/a; { фокальный параметр }
e:=c/a; { эксцентриситет }
ug:=pi-ugol*pi/180;
{ координаты фокуса } xf:=round( xc +f*cos(ug-pi));
yf:=round( yc +f*sin(ug-pi));
_TRACE(xf,yf,s,alf1,alf2,co, 1, p,e,ug);{ первая ветка кривой }
_TRACE(xf,yf,s,alf1,alf2,co,-1, p,e,ug) { вторая ветка кривой }
end;
{---------------------------------------------------------}
PROCEDURE _PARAB(xc,yc, ugol, a,s,alf1,alf2, co: integer);
{ xc,yc - вершина параболы, ugol - наклон оси,
a - расстояние от вершины до фокуса, s - размер,
alf1..alf2 - диапазон изменения полярного угла, со - цвет }
var
xf,yf: integer; p,ug: real;
begin
if( a<=0)or( s<=0) then exit; R
ug:=pi-ugol*pi/180; p
p:=2*a; { фокальный параметр }
{ координаты фокуса } С F
xf:=round( xc+a*cos(ug-pi));
yf:=round( yc+a*sin(ug-pi));
_TRACE(xf,yf,s,alf1,alf2,co, 1,p,1,ug); { первая ветка кривой }
_TRACE(xf,yf,s,alf1,alf2,co,-1,p,1,ug) { вторая ветка кривой }
end;