Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Разбор процедуры по графике / 2 сообщений из 2, страница 1 из 1
21.12.2006, 01:03
    #34214759
The_answer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбор процедуры по графике
Вот исходнывй код программы, но не хватает одной процедуры. Код взят с сайта algolist.manual.ru. А чем дополнить процедцуру V_GetPclip?

Текст программы:
#include <graphics.h>
static float Wxlef= 100.0, Wybot= 100.0, Wxrig= 300.0,Wytop= 200.0;
static float Wxrect[4]= {100.0, 100.0, 300.0, 300.0 };
static float Wyrect[4]= {100.0, 200.0, 200.0, 100.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;

void V_GetRclip (xleft, ybottom, xright, ytop)
float *xleft, *ybottom, *xright, *ytop;
{
*xleft= Wxlef; *ybottom= Wybot;
*xright= Wxrig; *ytop= Wytop;
}


int V_SetRclip (xleft, ybottom, xright, ytop)
float xleft, ybottom, xright, ytop;
{ int otw;
otw= 0;
if (xleft >= xright || ybottom >= ytop) ++otw; else {
Windn= 4;
Windx= Wxrect; Windy= Wyrect;
Wxlef= Wxrect[0]= Wxrect[1]= xleft;
Wybot= Wyrect[0]= Wyrect[3]= ybottom;
Wxrig= Wxrect[2]= Wxrect[3]= xright;
Wytop= Wyrect[1]= Wyrect[2]= ytop;
Wnormx= WxNrec; Wnormy= WyNrec; /* Нормали */
WxNrec[0]= 1; WyNrec[0]= 0;
WxNrec[1]= 0; WyNrec[1]= -1;
WxNrec[2]= -1; WyNrec[2]= 0;
WxNrec[3]= 0; WyNrec[3]= 1;
}
return (otw);
} /* V_SetRclip */


void V_GetPclip (kv, wx, wy, nx, ny)
float *xleft, *ybottom, *xright, *ytop,*kv1;
{
*xleft= wx; *ybottom= nx;
*xright= wy; *ytop= ny;*kv1=kv;
}


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);
}

int V_Plclip (N_in, X_in, Y_in, X_ou, Y_ou)
int N_in;
float *X_in, *Y_in, *X_ou, *Y_ou;
{
int ii, N_ou; float *ptr;

if ((N_ou= N_in) < 3) {N_ou= -1; goto all; }
if (Windn < 3) {N_ou= -2; goto all; }
for (ii=0; ii<Windn; ++ii) {
N_ou= Pl_clip0 (ii, N_ou, X_in, Y_in, X_ou, Y_ou);
ptr= X_in; X_in= X_ou; X_ou= ptr;
ptr= Y_in; Y_in= Y_ou; Y_ou= ptr;
}
if (!(Windn & 1)) {
ii= N_ou;
while (--ii >= 0) {*X_ou++= *X_in++; *Y_ou++= *Y_in++; }
}
all:
return N_ou;
}

static int Pl_clip0 (N_reb, N_in, X_in, Y_in, X_ou, Y_ou)
int N_reb, N_in;
float *X_in, *Y_in, *X_ou, *Y_ou;
{
int ii, jj;
int pozb, /* Коды расположения начальной точки */
pozn, /* многоугольника и точек тек стороны */
pozk; /* 0/1/2 - пред точка вне/на/внутри */
float Rx,Ry; /* Координаты начала ребра окна */
float Nx, Ny; /* Нормаль к ребру окна */
float xb, yb; /* Начальная точка многоугольника */
float xn, yn; /* Начальная точка текущей стороны */
float xk, yk; /* Конечная точка текущей стороны */
float t; /* Значение параметра точки пересечения */
float Qb,Qn,Qk; /* Скалярные произведения */
float *ptx_ou;

/* Запрос параметров ребра окна */
Rx= Windx[N_reb]; Ry= Windy[N_reb];
Nx= Wnormx[N_reb]; Ny= Wnormy[N_reb];

/* Цикл отсчения многоугольника ребром окна */
ii= 0; ++N_in; ptx_ou= X_ou;
while (--N_in >= 0) {
if (N_in) {
xk= *X_in++; yk= *Y_in++; /* Кон точка стороны */
Qk= (xk-Rx)*Nx + (yk-Ry)*Ny; /* Параметр положения */
pozk= 1; /* 1 - точка на гр. */
if (Qk < 0) --pozk; else /* 0 - точка вне */
if (Qk > 0) ++pozk; /* 2 - точка внутри */
} else {
xk= xb; yk= yb; Qk= Qb; pozk= pozb;
}
if (!ii) {
xb= xn= xk; yb= yn= yk; Qb= Qn= Qk; pozb= pozn= pozk;
++ii; continue;
}
jj= 0;
switch (pozn*3 + pozk) { /* Стар Нов Выход */
case 0: goto no_point; /* вне-вне нет */
case 1: goto endpoint; /* вне-на конечная */
case 2: goto intersec; /* вне-вну перес,кон */
case 3: goto no_point; /* на -вне нет */
case 4: /* на -на конечная */
case 5: goto endpoint; /* на -вну конечная */
case 6: goto no_end; /* вну-вне пересечен */
case 7: /* вну-на конечная */
case 8: goto endpoint; /* вну-вну конечная */
}
no_end: ++jj;
intersec:
t= Qn/(Qn-Qk);
*X_ou++= xn + t*(xk-xn);
*Y_ou++= yn + t*(yk-yn);
if (!jj) {
endpoint:
*X_ou++= xk; *Y_ou++= yk;
}
no_point:
xn= xk; yn= yk; Qn= Qk; pozn= pozk;
}
return (X_ou - ptx_ou);
} /* Pl_clip0 */


/*--------------------------------------------------- DrawPoly
* Чертит контур многоугольника
*/
void DrawPoly (col, n, x, y)
int col, n; float *x, *y;
{ int ii, jj;
setcolor (col);
for (ii=0; ii<n; ++ii) {
if ((jj= ii+1) >= n) jj= 0;
line (x[ii], y[ii], x[jj], y[jj]);
}
} /* DrawPoly */

/*---------------------------------------------------- CLR_STR
* Зачищает строку выводом в нее пробелов
*/
void CLR_STR (void)
{
printf (" \r");
}

/*------------------------------------------------ PLCLIP_MAIN
*/
void main (void)
{ int ii, jj,
fon; /* Индекс фона */
float Wxn,Wyn, /* Прямоугольный отсекатель */
Wxk,Wyk;
int N_wind= 0; /* Вводимый отсекатель */
float X_wind[100],
Y_wind[100];
float X_norm[100],
Y_norm[100];
int wnum; /* Запрошенный отсекатель */
float *wx,*wy,*wnx,*wny;
int N_poly= 0; /* Отсекаемый многугольник */
float X_poly[100],
Y_poly[100];
int N_clip= 0; /* Отсеченный многугольник */
float X_clip[100],
Y_clip[100];
int entry= 0; /* 0/1 - нет/был вывод по умолчанию */
int gdriver= DETECT, gmode;

initgraph (&gdriver, &gmode, "");
fon= 0; /* Цвет фона */

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

/*--------------- Установить окно отсечения ----------------*/
new_window:
gotoxy (1,1);
if (!entry) {
N_wind= 8; wx= X_wind; wy= Y_wind;
*wx++= 150; *wx++= 100; *wx++= 100; *wx++= 150;
*wy++= 100; *wy++= 150; *wy++= 250; *wy++= 300;

*wx++= 250; *wx++= 300; *wx++= 300; *wx++= 250;
*wy++= 300; *wy++= 250; *wy++= 150; *wy++= 100;
goto wr_window;
}
if (!N_poly) goto set_rect;





/*---------- Задание многоугольного окна отсечения ---------*/
set_window:
CLR_STR ();
printf ("----Vertexs in clip window= %d ? ", N_wind);
scanf ("%d", &N_wind);
if (N_wind < 0) goto all;
if (!N_wind) goto set_rect;
for (ii=0; ii<N_wind; ++ii) {
CLR_STR ();
printf ("X_wind[%d], Y_wind[%d] ? ", ii, ii);
scanf ("%f%f", &X_wind[ii], &Y_wind[ii]);
}
wr_window:
jj= V_SetPclip (N_wind, X_wind, Y_wind, X_norm, Y_norm);
if (jj) {
printf ("Error=%d in polyline window\n", jj);
goto set_window;
} else goto ou_win;





/*---------- Задание прямоугольного окна отсечения ---------*/
set_rect:
V_GetRclip (&Wxn, &Wyn, &Wxk, &Wyk);
get_rect:
CLR_STR ();
printf ("Rect window: (Xn=%f Yn=%f Xk=%f Yk=%f) ? ",
Wxn, Wyn, Wxk, Wyk);
scanf ("%f%f%f%f", &Wxn, &Wyn, &Wxk, &Wyk);
wr_rect:
jj= V_SetRclip (Wxn, Wyn, Wxk, Wyk);
if (jj) {
printf ("Error=%d in rectangle window\n", jj);
goto get_rect;
}





/*--------------- Прорисовка окна отсечения ----------------*/
ou_win:
wnum= V_GetPclip(&wx, &wy, &wnx, &wny);
DrawPoly (LIGHTRED, wnum, wx, wy);





/*------- Ввод координат отсекаемого многоугольника --------*/

set_poly:
gotoxy (1,1);
if (!entry) { /* При первом входе отрисовка по умолчанию */
N_poly= 3;
X_poly[0]= 10; X_poly[1]= 90; X_poly[2]= 170;
Y_poly[0]= 160; Y_poly[1]= 220; Y_poly[2]= 160;
} else {
CLR_STR ();
printf ("--- Vertexs in polyline= %d ? ",N_poly);
scanf ("%d", &N_poly);
if (N_poly <= 0) goto new_window;
for (ii=0; ii<N_poly; ++ii) {
printf (" \r");
printf ("X_poly[%d], Y_poly[%d] ? ", ii, ii);
scanf ("%f%f", &X_poly[ii], &Y_poly[ii]);
}
}
++entry;

/*---------- Прорисовка отсекателя и отсекаемого -----------*/
wnum= V_GetPclip (&wx, &wy, &wnx, &wny);
DrawPoly (LIGHTRED, wnum, wx, wy);
DrawPoly (LIGHTGREEN, N_poly, X_poly, Y_poly);


/*----------------------- Отсечение ------------------------*/
N_clip= V_Plclip(N_poly, X_poly, Y_poly, X_clip, Y_clip);

/*----------------- Прорисовка отсеченного -----------------*/
DrawPoly (YELLOW, N_clip, X_clip, Y_clip);
goto set_poly;

all:
closegraph();
} /* PLCLIP_MAIN */
...
Рейтинг: 0 / 0
21.12.2006, 14:37
    #34216142
tchingiz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбор процедуры по графике
над окном редактирования сообщения есть кнопочка src.
Используется для записи текстов программ в сообщении
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Разбор процедуры по графике / 2 сообщений из 2, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]