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

Вид материалаУчебное пособие

Содержание


0.17.6  Тест процедуры V_FAST
0.18  Приложение 7. Процедуры отсечения отрезка
0.18.1  V_SetPclip - установить многоугольник отсечения
Подобный материал:
1   ...   36   37   38   39   40   41   42   43   44

0.17.6  Тест процедуры V_FAST


/*-------------------------------------------------- FAST_MAIN

*/

void main (void)

{

int ii, kol, grn, new, entry;

int x_isx, y_isx;

int gdriver = DETECT, gmode;

int Px[256] = {200,200,250,270,270,210,210,230,230};

int Py[256] = {200,250,250,230,200,210,230,230,210};


kol= 5; /* Кол-во вершин */

grn= 11; /* Код пикселов границы */

new= 14; /* Код заливки */

x_isx= 240; /* Координаты затравки */

y_isx= 240;

entry= 0;


initgraph(&gdriver, &gmode, "c:\tc\bgi");

if ((ii= graphresult()) != grOk) {

printf ("Err=%d\n", ii); goto all;

}


m0:goto m2;

m1:++entry;

printf("Vertexs, boundary_pixel, new_pixel= (%d %d %d) ? ",

kol, grn, new);

scanf ("%d%d%d", &kol, &grn, &new);

if (kol < 0) goto all;


for (ii=0; ii
printf ("Px[%d], Py[%d] = ? ", ii, ii);

scanf ("%d%d", &Px[ii], &Py[ii]);

}


printf ("X,Y isx= (%d %d) ? ", x_isx, y_isx);

scanf ("%d%d", &x_isx, &y_isx);


m2:

setbkcolor(0);

cleardevice();


/* Построение границы */

setcolor (grn);

for (ii= 0; ii
line (Px[ii], Py[ii], Px[ii+1], Py[ii+1]);

line (Px[kol-1], Py[kol-1], Px[0], Py[0]);


/* При первом входе строится квадратик дырки */

if (!entry) {

for (ii= kol; ii
line (Px[ii], Py[ii], Px[ii+1], Py[ii+1]);

line (Px[kol+3], Py[kol+3], Px[kol], Py[kol]);

}


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

V_FA_SET (getmaxx()+1, getmaxy()+1, MAX_STK);


stklen= 0; /* Занятое кол-во байт в стеке */


/* Заливка */

ii= V_FAST (grn, new, x_isx, y_isx);

printf ("Answer= %d MaxStack=%d\n", ii, stklen);

goto m1;


all:

closegraph();

}

0.18  Приложение 7. Процедуры отсечения отрезка


В данном приложении приведены процедуры, обеспечивающие выполнение отсечения по прямоугольному и многоугольному выпуклому окну и тестовая программа проверки работы процедур отсечения.

/*=================================================== V_CLIP.C

*

* Подрограммы, связанные с отсечением:

*

* V_SetPclip - установить размеры многоугольного окна

* отсечения

* V_SetRclip - установить размеры прямоугольного окна

* отсечения

* V_GetRclip - опросить размеры прямоугольного окна

* отсечения

* V_CSclip - отсечение по алгоритму Коэна-Сазерленда

* прямоугольное окно, кодирование

* концов отсекаемого отрезка

* V_FCclip - отсечение по алгоритму быстрого отсечения

* Алгоритм Собкова-Поспишила-Янга -

* прямоугольное окно, кодирование

* отсекаемого отрезка

* V_LBclip - отсечение по алгоритму Лианга-Барски

* прямоугольное окно, параметрическое

* представление линий

* V_CBclip - отсечение по алгоритму Кируса-Бека

* окно - выпуклый многоугольник,

* параметрическое представление линий

*/


/* Глобальные скаляры для алгоритмов отсечения по

* прямоугольному окну - Коэна-Сазерленда, Fc-алгоритм,

* Лианга-Барски

*/

static float Wxlef= 0.0, /* Координаты левого нижнего и */

Wybot= 0.0, /* правого верхнего углов окна */

Wxrig= 7.0, /* отсечения */

Wytop= 5.0;


/* Глобальные скаляры для алгоритма Кируса-Бека

* отсечения по многоугольному окну

*/


/* Координаты прямоугольного окна */

static float Wxrect[4]= {0.0, 0.0, 7.0, 7.0 };

static float Wyrect[4]= {0.0, 5.0, 5.0, 0.0 };


/* Перепендикуляры к сторонам прямоугольного окна */

static float WxNrec[4]= {1.0, 0.0, -1.0, 0.0 };

static float WyNrec[4]= {0.0, -1.0, 0.0, 1.0 };


/* Данные для многоугольного окна */

static int Windn=4; /* Кол-во вершин у окна */

static float *Windx= Wxrect, /* Координаты вершин окна */

*Windy= Wyrect;

static float *Wnormx= WxNrec, /* Координаты нормалей */

*Wnormy= WyNrec;

0.18.1  V_SetPclip - установить многоугольник отсечения


/*------------------------------------------------- V_SetPclip

* Устанавливает многоугольное окно отсечения

* kv - количество вершин в окне

* wx - X-координаты вершин

* wy - Y-координаты вершин

* nx - X-координаты нормалей к ребрам

* ny - Y-координаты нормалей к ребрам

*

* Проверяет окно на выпуклость и невырожденность

*

* Если окно правильное, то

* 1. Обновляет глобалы описания многоугольного окна:

* Windn= kv;

* Windx= wx; Windy= wy; --Координаты вершин окна

* Wnormx= nx; Wnormy= ny; --Координаты перпендикуляров

*

* 2. Вычисляет координаты перепендикуляров к сторонам окна

*

* Возвращает:

* 0 - норма

* 1 - вершин менее трех

* 2 - многоугольник вырожден в отрезок

* 3 - многоугольник невыпуклый

*/


int V_SetPclip (kv, wx, wy, nx, ny)

int kv; float *wx, *wy, *nx, *ny;

{ int ii, jj, sminus, splus, szero, otw;

float r,

vox, voy, /* Координаты (i-1)-й вершины */

vix, viy, /* Координаты i-й вершины */

vnx, vny; /* Координаты (i+1)-й вершины */


/* Проверка на выпуклость

* для этого вычисляются векторные произведения

* смежных сторон и определяется знак

* если все знаки == 0 то многоугольник вырожден

* если все знаки >= 0 то многоугольник выпуклый

* если все знаки <= 0 то многоугольник невыпуклый

*/

otw= 0;

if (--kv < 2) {++otw; goto all; }

sminus= 0;

splus= 0;

szero= 0;

vox= wx[kv]; voy= wy[kv];

vix= *wx; viy= *wy;

ii= 0;

do {

if (++ii > kv) ii= 0; /* Следующая вершина */

vnx= wx[ii]; vny= wy[ii]; /* Координаты (i+1)-й */

r= (vix-vox)*(vny-viy) - /* Вект произв ребер */

(viy-voy)*(vnx-vix); /* смежных с i-й верш */

if (r < 0) ++sminus; else

if (r > 0) ++splus; else ++szero;

vox= vix; voy= viy; /* Обновлен координат */

vix= vnx; viy= vny;

} while (ii);


if (!splus && !sminus) /* Все векторные равны нулю */

{otw= 2; goto all; } /* Многоугольник вырожден */

if (splus && sminus) /* Знакопеременн. векторные */

{otw= 3; goto all; } /* Многоугольник невыпуклый */


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

Windn= kv+1; /* Количество вершин у окна */

Windx= wx; Windy= wy; /* Координаты вершин окна */

Wnormx= nx; Wnormy= ny; /* Координ. перпендикуляров */


/* Вычисление координат перпендикуляров к сторонам */


vox= *wx; voy= *wy;

ii= 0;

do {

if (++ii > kv) ii= 0;

vix= wx[ii]; viy= wy[ii]; /* Текущая вершина */

vnx= viy-voy; vny= vox-vix; /* Поворот по часовой */

if (splus) { /* Внутр нормали влево */

vnx= -vnx; vny= -vny;

}

*nx++= vnx; *ny++= vny;

vox= vix; voy= viy; /* Обновление координат */

} while (ii);


all:

return (otw);

} /* V_SetPclip */