Новосибирский Государственный Технический Университет. Факультет автоматики и вычислительной техники Кафедра вычислительной техники (специальность 220100). учебное пособие

Вид материалаУчебное пособие
0.13.2  V_Bre - алгоритм Брезенхема
0.13.3  V_BreM - модифицированный алгоритм Брезенхема
0.13.4  T_VECTOR - тестовая программа генерации векторов
Подобный материал:
1   ...   29   30   31   32   33   34   35   36   ...   44

0.13.2  V_Bre - алгоритм Брезенхема


/*----------------------------------------------------- V_Bre

* void V_Bre (int xn, int yn, int xk, int yk)

*

* Подпрограмма иллюстрирующая построение вектора из точки

* (xn,yn) в точку (xk, yk) методом Брезенхема.

*

* Построение ведется от точки с меньшими координатами

* к точке с большими координатами с единичным шагом по

* координате с большим приращением.

*

* В общем случае исходный вектор проходит не через вершины

* растровой сетки, а пересекает ее стороны.

* Пусть приращение по X больше приращения по Y и оба они > 0.

* Для очередного значения X нужно выбрать одну двух ближайших

* координат сетки по Y.

* Для этого проверяется как проходит исходный вектор - выше

* или ниже середины расстояния между ближайшими значениями Y.

* Если выше середины, то Y-координату надо увеличить на 1,

* иначе оставить прежней.

* Для этой проверки анализируется знак переменной s,

* соответствующей разности между истинным положением и

* серединой расстояния между ближайшими Y-узлами сетки.

*/


void V_Bre (xn, yn, xk, yk)

int xn, yn, xk, yk;

{ int dx, dy, s, sx, sy, kl, swap, incr1, incr2;


/* Вычисление приращений и шагов */

sx= 0;

if ((dx= xk-xn) < 0) {dx= -dx; --sx;} else if (dx>0) ++sx;

sy= 0;

if ((dy= yk-yn) < 0) {dy= -dy; --sy;} else if (dy>0) ++sy;

/* Учет наклона */

swap= 0;

if ((kl= dx) < (s= dy)) {

dx= s; dy= kl; kl= s; ++swap;

}

s= (incr1= 2*dy)-dx; /* incr1 - констан. перевычисления */

/* разности если текущее s < 0 и */

/* s - начальное значение разности */

incr2= 2*dx; /* Константа для перевычисления */

/* разности если текущее s >= 0 */

PutPixLn (xn,yn,Pix_C); /* Первый пиксел вектора */

while (--kl >= 0) {

if (s >= 0) {

if (swap) xn+= sx; else yn+= sy;

s-= incr2;

}

if (swap) yn+= sy; else xn+= sx;

s+= incr1;

PutPixLn (xn,yn,Pix_C); /* Текущая точка вектора */

}

} /* V_Bre */

0.13.3  V_BreM - модифицированный алгоритм Брезенхема


/*----------------------------------------------------- V_BreM

* void V_BreM (int xn, int yn, int xk, int yk)

*

* Подпрограмма иллюстрирующая построение ребра залитого

* многоугольника из точки (xn,yn) в точку (xk,yk)

* модифициpованным методом Брезенхема.

*

* Строки многоугольника от занесенного пиксела границы до xk

* заполняются оттенком с максимальным номером.

*/


void V_BreM (xn, yn, xk, yk)

int xn, yn, xk, yk;

{ int dx, dy, sx, sy, kl, swap;

long incr1, incr2;

long s; /* Текущее значение ошибки */

long s_max; /* Макс значение ошибки */

int color_tek; /* Текущий номеp оттенка */

int xt;


/* Вычисление приращений и шагов */

sx= 0;

if ((dx= xk-xn) < 0) {dx= -dx; --sx;} else if (dx>0) ++sx;

sy= 0;

if ((dy= yk-yn) < 0) {dy= -dy; --sy;} else if (dy>0) ++sy;

/* Учет наклона */

swap= 0;

if ((kl= dx) < (s= dy)) {dx= s; dy= kl; kl= s; ++swap;}

s= (long)dx*(long)Pix_V; /* Hачальное значение ошибки */

incr1= 2l*(long)dy /* Конст. перевычисления ошибки */

*(long)Pix_V; /* если текущее s < s_max */

incr2= 2l*s; /* Конст. перевычисления ошибки */

/* если текущее s >= s_max */

s_max= incr2 - incr1; /* Максимальное значение ошибки */

color_tek= Pix_V; /* Яpкость стаpтового пиксела */

if (dx)color_tek=(int)((((long)Pix_V*(long)dy)/(long)dx)/2l);

PutPixLn (xn, yn, Pix_C+color_tek); /* 1-й пиксел */

while (--kl >= 0) {

if (s >= s_max) {

if (swap) xn+= sx; else yn+= sy;

s-= incr2;

}

if (swap) yn+= sy; else xn+= sx;

s+= incr1;

color_tek= Pix_V;

if (dx) color_tek= s / dx /2;

PutPixLn (xn,yn,Pix_C+color_tek); /* Тек.пиксел */

/* Однотонная закраска строки многоугольника макс цветом */

xt= xn;

while (++xt <= xk) PutPixLn (xt,yn,Pix_C+Pix_V-1);

}

} /* V_BreM */

0.13.4  T_VECTOR - тестовая программа генерации векторов


/*================================================= T_VECTOR.C

* ТЕСТ ГЕНЕРАЦИИ ВЕКТОРОВ

*

* Строит вектора из точки Xn,Yn в заданную

* Программа запрашивает ввод четыpех чисел:

* mode = -2 - прекращение работы

* -1 - очистка экрана

* 0 - вывод сетки

* 1-7 построение вектоpа:

* 1рр == 1 - по алгоритму ЦДА

* 2рр == 1 - по алгоритму Брезенхема

* 3рр == 1 - по модифиц. алгоритму Брезенхема

* иное значение - замена Xn,Yn на введенные Xk,Yk

* atrib - атpибуты постpоения в виде десятичного числа

* из 8 цифр - PPСCCVVV:

* PP - pазмеp элементаpного пиксела

* ССС - начальный номер оттенка

* VVV - количество оттенков

* Xk - конечная координата вектора

* Yk

*/


#include "V_VECTOR.C"


#define MODE_256 1 /* 0/1 - обычный VGA/SVGA режим */


#if MODE_256

# include "V_SVGA.C"

#endif


#include

#include

#include

#include


/*------------------------------------------------------- Grid

* Строит сетку 10*10

*/


void Grid (int col)

{ int Xn,Yn,Xk,Yk;

setcolor (col);

Xn= 0; Xk= getmaxx();

Yn= 0; Yk= getmaxy();

while (Xn <= Xk) {line (Xn,Yn,Xn,Yk); Xn+= 10; }

Xn= 0;

while (Yn <= Yk) {line (Xn,Yn,Xk,Yn); Yn+= 10; }

} /* Grid */


/*----------------------------------------- MAIN T_VECTOR.C */


void main (void)

{

int ii, jj,

mode=1, /* Режим pаботы */

Xn=0,Yn=0, /* Координаты начала отрезка */

Xk,Yk, /* Координаты конца отрезка */

fon, /* Индекс цвета фона */

col_beg, col_val, /* Атpибуты пикселов */

xpix, ypix,

colgrid, /* Цвет сетки */

col_lin= 200, /* Цвет "точного" отрезка */

col_Bre= 201, /* Цвет построения для ЦДА */

col_DDA= 202; /* Цвет построения для Брезенхема */

int gdriver= DETECT, gmode;

long atrib=5064064l,la;/* Размеp пиксела*100+цвета */


#if MODE_256

V_ini256 (&gdriver, &gmode, "");

jj= getmaxcolor();

for (ii=0; ii<=jj; ++ii) /* Ч/б палитра */

setrgbpalette (ii, ii, ii, ii);

atrib=5064064l; /* Пиксел 5х5, нач цвет=64*/

colgrid= 170; /* Цвет сетки */

fon= 140;

setrgbpalette(7,255,255,255);/* Цвет для printf */

#else

initgraph (&gdriver, &gmode, "");

atrib= 5000016l; /* Пиксел 5х5, нач цвет=0*/

colgrid= 9;

fon= 8;

#endif


setbkcolor(fon); /* Очистка экрана */

cleardevice();

Xk= getmaxx(); Yk= getmaxy();


Grid (colgrid);


/* Цвет для построения алгоритмом ЦДА */

setrgbpalette(col_lin,63, 0,0); /* Цвет точного отрезка */

setrgbpalette(col_DDA,63,63,0); /* Цвет для ЦДА */

setrgbpalette(col_Bre,00,63,0); /* Цвет для Брезенхема */


for (;;) {

gotoxy (1, 1);

printf(" ");

printf(" \r");

printf("mode atrib Xk Yk= (%d %ld %d %d) ? ",

mode, atrib, Xk, Yk);

scanf ("%d%ld%d%d", &mode, &atrib, &Xk, &Yk);

xpix= ypix= atrib / 1000000l;

la= atrib % 1000000l;

col_beg= la / 1000l;

col_val= la % 1000l;

if (mode == -2) goto konec; else

if (mode == -1) cleardevice(); else

if (!mode) Grid (colgrid); else

if (mode & 7) {

if (mode & 1) {

V_setlin (xpix, ypix, col_DDA, 1);

V_DDA (Xn, Yn, Xk, Yk);

/* Постpоение "точного" отpезка */

setcolor (col_lin);

line (Xn, Yn, Xk*xpix, Yk*ypix);

}

if (mode & 2) {

V_setlin (xpix, ypix, col_Bre, 1);

V_Bre (Xn, Yn+3, Xk, Yk+3);

/* Постpоение "точного" отpезка */

setcolor (col_lin);

line (Xn, (Yn+3)*ypix, Xk*xpix, (Yk+3)*ypix);

}

if (mode & 4) {

V_setlin (xpix, ypix, col_beg, col_val);

V_BreM (Xn, Yn+6, Xk, Yk+6);

/* Постpоение "точного" отpезка */

setcolor (col_lin);

line (Xn, (Yn+6)*ypix, Xk*xpix, (Yk+6)*ypix);

}

} else {

Xn= Xk; Yn= Yk;

}

}

konec:

closegraph();

} /* main */