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

Вид материалаУчебное пособие
0.12  Приложение 1. Процедуры преобразований 0.13  Приложение 2. Процедуры генерации отрезков
0.13.1  V_DDA - несимметричный ЦДА
Подобный материал:
1   ...   28   29   30   31   32   33   34   35   ...   44

0.12  Приложение 1. Процедуры преобразований

0.13  Приложение 2. Процедуры генерации отрезков


Здесь приведены тексты соответствующих процедур с пояснениями и тестовая программа. Процедуры позволяют генерировать вектора в любом квадранте с использованием алгоритмов несимметричного цифрового дифференциального анализатора и Брезенхема, а также построения ребра, ограничивающего заполненный многоугольник, модифицированным алгоритмом Брезенхема, уменьшающим лестничный эффект.

Предусмотрена возможность задания атрибутов формируемых отрезков - номер цвета и размер пиксела, используемого при формировании отрезков.

В тестовой программе предусмотрено, что при наличии SVGA-адаптера он может использоваться как в обычном режиме, так и в режиме до 1024x768 точек с 256 цветами.

/*------------------------------------------------- V_VECTOR.C

* Подпрограммы генерации векторов

*/


#include

#include


#define PutMay putpixel


static int Pix_X= 3, /* Размер пиксела по X */

Pix_Y= 3, /* Размер пиксела по Y */

Pix_C= 64, /* Нач. индекс цвета пиксела */

Pix_V= 64; /* Количество оттенков */


/*--------------------------------------------------- PutPixLn

* Подпрограмма заносит "кpупный" пиксел в позицию X,Y

* Точка (0, 0) - левый верхний угол экрана.

* Размеры пиксела задается фактическими паpаметpами x и y.

* Hомер оттенка пиксела задается фактическим паpаметpом c.

*/


void PutPixLn (int x, int y, int c)

{ int ii, jj, kk;

x *= Pix_X; y *= Pix_Y;

ii= Pix_Y;

while (--ii >= 0) {

jj= Pix_X; kk= x;

while (--jj >= 0) PutMay (kk++, y, c);

y++;

}

} /* PutPixLn */


/*--------------------------------------------------- V_setlin

* Устанавливает атрибуты построения линий:

* размер элементарного пиксела, индекс цвета, кол-во оттенков

* Если размер <= 0, то он не меняется

* Если атрибут цвета < 0, то он не меняется

*/

void V_setlin (sizex, sizey, colorindex, colorvalue)

int sizex, sizey, colorindex;

{

if (sizex > 0) Pix_X= sizex;

if (sizey > 0) Pix_Y= sizey;

if (colorindex >= 0) Pix_C= colorindex;

if (colorvalue >= 0) Pix_V= colorvalue;

} /* V_setlin */

0.13.1  V_DDA - несимметричный ЦДА


/*----------------------------------------------------- V_DDA

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

*

* Подпрограмма построения вектора из точки (xn,yn)

* в точку (xk, yk) в первом квадранте методом

* несимметричного цифрового дифференциального анализатора

* с использованием только целочисленной арифметики.

*

* Обобщение на другие квадранты труда не составляет.

*

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

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

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

*

* Отдельно выделяется случай вектора с dx == dy

*

* Всего надо выдать пикселы в dx= xk - xn + 1 позиции

* по оси X и в dy= yk - yn + 1 позиции по оси Y.

*

* Для определенности рассмотрим случай dx > dy

*

* При приращении X-координаты на 1 Y-координата должна

* увеличиться на величину меньшую единицы и равную dy/dx.

*

* После того как Y-приращение станет больше или равно 1.0,

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

* накопленного приращения вычесть 1.0 и продолжить построения

* Т.е. приращение Y на 1 выполняется при условии:

* dy/dx + dy/dx + ... + dy/dx >= 1.0

* Т.к. вычисления в целочисленной арифметике быстрее, то

* умножим на dx обе части и получим эквивалентное условие:

* dy + dy + ... + dy >= dx

*

* Эта схема и реализована в подпрограмме.

*

* При реализации на ассемблере можно избавиться от

* большинства операторов внутри цикла while.

* Для этого перед циклом надо домножить dy на величину,

* равную 65536/dx.

* Тогда надо увеличивать Y на 1 при признаке переноса

* после вычисления s, т.е. операторы

* s= s + dy;

* if (s >= dx) { s= s - dx; yn= yn + 1; }

* заменяются командами ADD и ADC

*

*/


void V_DDA (xn, yn, xk, yk)

int xn, yn, xk, yk;

{ int dx, dy, s;


/* Упорядочивание координат и вычисление приращений */

if (xn > xk) {

s= xn; xn= xk; xk= s;

s= yn; yn= yk; yk= s;

}

dx= xk - xn; dy= yk - yn;


/* Занесение начальной точки вектора */

PutPixLn (xn, yn, Pix_C);


if (dx==0 && dy==0) return;


/* Вычисление количества позиций по X и Y */

dx= dx + 1; dy= dy + 1;


/* Собственно генерация вектора */

if (dy == dx) { /* Наклон == 45 градусов */

while (xn < xk) {

xn= xn + 1;

PutPixLn (xn, xn, Pix_C);

}

} else if (dx > dy) { /* Наклон < 45 градусов */

s= 0;

while (xn < xk) {

xn= xn + 1;

s= s + dy;

if (s >= dx) { s= s - dx; yn= yn + 1; }

PutPixLn (xn, yn, Pix_C);

}

} else { /* Наклон > 45 градусов */

s= 0;

while (yn < yk) {

yn= yn + 1;

s= s + dx;

if (s >= dy) { s= s - dy; xn= xn + 1; }

PutPixLn (xn, yn, Pix_C);

}

}

} /* V_DDA */