X = x0, Y = y0
Dx = x1–x0, Dy = y1-y0
E = -Dx
for i = 0 to Dx
point(X,Y)
X = X + 1
E = E + 2×Dy
while(E ³ 0)
Y = Y + 1
E = E - 2*Dx
end while
next i
finish
Если (Dx,Dy) принадлежат не первой октанте, то точки (X,Y) генерируются симметрично. Подробнее, пусть x0, y0, x1, y1 - произвольные целые числа. Тогда, если |Dx| ³ |Dy| , то вектор (Dx,Dy) находится в одной из октант I, IV, V, VIII. В этом случае координата X генерируемой точки получает на каждом шаге приращение sign(Dx). Если же |Dx| < |Dy|, то надо придавать приращение sign(Dy) координате Y. Приходим к окончательной версии алгоритма Брезенхема.
x0, y0, x1, y1 - входные параметры, целые
X, Y, dX, dY, E, sx, sy, temp, swap, i - целые
dX = |x1-x0|, dY = |y1-y0|
sx = sign(x1-x0) , sy = sign(y1-y0)
if dY > dX (если направление Y - главное)
temp = dX, dX=dY, dY=temp - переставить dX и dY
swab = 1 - была перестановка
else swab = 0
end if-else
E = -dX
for i = 0 to dX
point(X,Y)
E = E + 2×dY
while (E ³ 0)
if (swab = 1) X = X + sx
else Y = Y + sy
end if-else
E = E – 2×dX
end while
if (swab = 1) Y = Y + sy
else X = X + sx
end if-else
next i
finish
Пример программной реализации алгоритма Брезенхема приводится также в пп. 2.2 (пример 2.1).
Программа
//Метод Брезенхема
#include <conio.h>
#include <graphics.h>
#include <math.h>
int x0, y0; //Координаты центра системы координат относит. лев. верх. угла
int hx=3, hy=3; //1/2 ширины и длины пиксела
//Вывод "крупного" пиксела на экран
void point(int ix, int iy)
{bar(x0+hx*2*ix-hx+1, y0-hy*2*iy-hy+1,x0+hx*2*ix+hx-1, y0-hy*2*iy+hy-1);}
//Функция вывода отрезка по алгоритму Брезенхема
void bresenham(int ix0, int iy0, int ix1, int iy1)
{
int ix, iy, delta_x, delta_y, esh, sx, sy;
int register temp, swab, i;
ix=ix0; iy=iy0;
delta_x=abs(ix1-ix0); delta_y=abs(iy1-iy0);
if (ix1-ix0>=0) sx=1; else sx=-1;
if (iy1-iy0>=0) sy=1; else sy=-1;
if (ix1==ix0) sx=0;
if (iy1==iy0) sy=0;
//Обмен значений delta_x delta_y в зависимости от угла
if (delta_y > delta_x)
{
temp=delta_x;
delta_x=delta_y;
delta_y=temp;
swab=1;
}
else swab=0;
//Инициализация Е с поправкой на половину пиксела
esh=2*delta_y-delta_x;
for(i=0;i<=delta_x;i++)
{
point(ix,iy);
while(esh>=0)
{
if (swab==1) ix=ix+sx; else iy=iy+sy;
esh=esh-2*delta_x;
}
if (swab==1)iy=iy+sy; else ix=ix+sx;
esh=esh+2*delta_y;
}
}
void main()
{
int gdriver=DETECT, gmode;
initgraph (&gdriver, &gmode, "");
x0=getmaxx()/2; y0=getmaxy()/2;
moveto(0,y0); linerel(getmaxx(),0); //Вывод осей координат
moveto(x0,0); linerel(0, getmaxy());
bresenham(0,0,5,3); //Вывод отрезка
getch(); //Ожидание нажатия клавиши
closegraph(); //Выключение графического режима
}
Результаты работы программы приведены на рис. 3.
Примечание. Для улучшения качества изображения применяются алгоритмы сглаживания лестничного эффекта. Точки, находящиеся дальше от прямой, выводятся с меньшей интенсивностью, чем те, которые находятся на прямой. В алгоритме Брезенхема в качестве меры удаленности может быть принят параметр E.
Метод приращений. В пп. 2.3 мы рассмотрим метод приращений для генерации точек кривой. Метод приращений также можно применить и для генерации точек прямой.
Запишем уравнение прямой, проходящей через точки (x0, y0) и (x1, y1), в виде f(x,y)= 0, а именно: f(x,y)=Dy(x-x0) - Dx(y-y0) = 0, где Dx = x1-x0 и Dy=y1-y0. Все точки области, содержащей отрезок прямой f(x,y)= 0, можно разбить на три множества: множество точек, принадлежащих прямой (для этих точек выполняется условие f(x,y)= 0), множество точек, расположенных справа от прямой (для них выполнено условие f(x,y) > 0), и множество точек, расположенных слева от прямой (для них выполнено условие f(x,y) < 0). Основную идею метода приращений можно сформулировать следующим образом. Если мы выставили точку слева от прямой, то мы стремимся перейти на правую сторону от прямой и наоборот.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.