С для профессиональных программистов

       

Вычерчивание линий


Функции вычерчивания линий являются основными подпрограммами графики и используются для отображения линий в заданном цвете путем задания ее начальных и конечных координат. В то время, как изображение вертикальных и горизонтальных линий не представляет особого труда, более трудной задачей является создание функций, которые рисуют линии вдоль диагоналей. Например, какие точки составляют линию, вычерчиваемую от точки с координатами 0,0 до точки с координатами 80,120?

Один из подходов к разработке функций вычерчивания линий использует отношение между смещением по координатам X и Y. Чтобы показать этот подход в действии, проведем линию между точками с координатами 0,0 и 5,10. Смещение по X равно 5, а по Y - 10. Отношение равно 1/2. Оно будет использоватся при определении коэффициента зависимости, по которому должны меняться координаты X и Y при изображении линий. В данном случае это означает, что приращение координаты X составляет половину величины изменения координаты Y. Начинающий программист часто использует этот метод при разработке функций вычерчивания линий. Хотя такой подход математически верен и прост для понимания, для его правильной работы и для того, чтобы избежать серьезных ошибок округления, необходимо использовать математические операции с числами с плавающей точкой. Это означает, что функции вычерчивания линий будут работать довольно медленно, если в систему не будет включен математический сопроцессор (например - Intel 8087). По этой причине этот метод используется довольно редко.

Наиболее общий    метод    изображения    линий                                                включает

использование  алгоритма  Брезенхама.  Хотя  основой в нем служит

также отношение между расстояниями по координатам X и Y, в данном

случае  не  требуется  выполнять  деление  или вычисление чисел с

плавающей  точкой.  Вместо  этого,  отношение  между   значениями

координат  X  и  Y  представляется  косвенным образом через серии

сложений  и  вычитаний.  Основной  идеей  алгоритма   Брезенхама,


является   регистрация   средних   значений   погрешностей  между

идеальным положением  каждой  точки  и  той  позицией  на  экране

дисплея,  в  которой она действительно отображается.  Погрешность

между идеальным и действительным положением точки возникает ввиду

ограниченных  возможностей  технических  средств.  Фактически  не

существует   дисплеев   с    бесконечно    большой    разрешающей





способностью,  и,  следовательно, действительное положение каждой

точки на линии требует наилучшей аппроксимации. В каждой итерации

цикла  вычерчивания  линии вызываются две переменные xerr и yerr,

которые  увеличиваются  в  зависимости   от   изменения   величин

координат  X  и  Y  соответственно.  Когда  значение  погрешности

достигает определенного значения,  оно  вновь  устанавливается  в

исходное   положение,   а   соответствующий   счетчик   координат

увеличивается.  Этот процесс продолжается до тех пор,  пока линия

не будет полностью вычерчена.  Функция line(),  приведенная ниже,

реализует этот метод.  Вы должны изучать ее до тех пор,  пока  не

поймете механизма выполнения всех ее операций. Заметим, что в ней

используется  функция   mempoint(),   разработанная   ранее   для

отображения точки на экране терминала.

/* Вычерчивание линии заданного цвета с использованием

алгоритма Брезенхама */

void line(startx,starty,endx,endy,color)

int startx,starty,endx,endy,color;

register int t,distаnce;

int xerr=0,yerr=0,delta_x,delta_y;

int incx,incy;

/* вычисление расстояния в обоих направлениях  */

delta_x=endx-startx;

delta_y=endy-starty;

/* определение направления шага,

шаг вычисляется либо по вертикальной, либо горизонтальной

линии   */

if (delta_x>0) incx=1;

else  if (delta_x==0) incx=0;

else  incx= -1;

if (delta_y>0) incy=1;

else  if (delta_y==0) incy=0;

else  incy= -1;

/* определение какое расстояние больше */

delta_x=abs(delta_x);

delta_y=abs(delta_y);

if (delta_x>delta_y) distance=delta_x;

else distance=delta_y;

/* вычерчивание линии */

for (t=0; t<=distance+1; t++)

mempoint(startx,starty,color);

xerr+=delta_x;

yerr+=delta_y;

if (xerr>distance)

xerr-=distance;

startx+=incx;

if (yerr>distance)

yerr-=distance;

starty+=incy;


Содержание раздела