else return 0;
}
//Функция вывода крупного пиксела
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 lineg (int x0, int y0, int x1, int y1)
{
int x=x0, y=y0;
int dx=x1-x0, dy=y1-y0;
int delta=0, ex=sign(dx), ey=sign(dy);
point (x,y);
//Если dx = 0, то выводится вертикальный отрезок
if (dx==0)
{while (y!=y1) point (x, ++y); return;}
//Если dy = 0, то выводится горизонтальный отрезок
if (dy==0)
{while (x!=x1) point (++x, y); return;}
//Если abs(dx) = abs(dy):
if (abs(dx)==abs(dy))
{
while (x!=x1) {x+=ex; y+=ey; point(x,y);}
return;
}
//Основной цикл
while (!(x==x1 && y==y1))
{
if (delta<=0)
{
if (dy*ex-dx*ey>0)
{
x+=ex; y+=ey; delta+=dy*ex-dx*ey;
point(x,y);
}
else
if (abs(dx)>abs(dy))
{
x+=ex; delta+=dy*ex;
point(x,y) ;
}
else
{
y+=ey; delta -=dx*ey;
point(x,y);
}
}
else
{
if (dy*ex-dx*ey<0)
{
x+=ex; y+=ey; delta+=dy*ex-dx*ey;
point(x,y);
}
else
if (abs(dx)>abs(dy))
{
x+=ex; delta+=dy*ex;
point(x,y);
}
else
{
y+=ey; delta-=dx*ey;
point(x,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());
line4(0,0,5,3);
getch();
closegraph();
}
Точки, выведенные на экран (рис. 5), отличаются от точек, генерируемых с помощью симметричного ЦДА.
Рис. 5. Метод приращений
Метод приращений, использующий четыре перемещения.
Алгоритм генерации точек прямой по методу приращений можно модифицировать следующим образом: выбор двух направлений перемещения точки производится не из восьми возможных направлений, а из четырех. Разрешается выбирать одно из вертикальных и одно из горизонтальных направлений перемещения точки.
Программа
//Метод приращений использующий четыре перемещения
#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 line4(int x0, int y0, int x1, int y1)
{
int dx=abs(x1-x0), dy=abs(y1-y0);
int ex, ey;
if (x1>x0) ex=1; else ex=-1;
if (y1>y0) ey=1; else ey=-1;
int E=0, x=x0, y=y0;
while((y!=y1) || (x!=x1))
{
point(x,y);
if (E>0) {E-=dx; y+=ey;} else {E+=dy; x+=ex;}
}
point(x,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());
line4(0,0,5,3); //Вывод отрезка
getch(); //Ожидание нажатия клавиши
closegraph(); //Выключение графического режима
}
Результаты работы программы приведены на рис. 6.
2.2. АЛГОРИТМЫ ЗАПОЛНЕНИЯ
Алгоритм с запоминанием точек границы в стек. Этот алгоритм предназначен для генерации точек выпуклого многоугольника. Определим отношение "<" (лексикографического) порядка на множестве точек плоскости следующим образом: (x,y) < (x',y'), если y < y' или y = y' и x > x'. Будем обходить против часовой стрелки точки границы многоугольника, начиная с вершины многоугольника, наименьшей среди всех его вершин относительно введенного отношения порядка. При увеличении значения ординаты точки, координаты предыдущей точки запоминаются в стек. Если же ордината Y уменьшилась, то извлекается точка из стека и соединяется с текущей точкой. Поскольку величина Y изменяется на ±1, достаточно хранить в стеке только координату X. Ниже мы рассмотрим реализацию, при которой стек представляется в виде массива (пример 2.1).
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.