
Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
21.12.2006, 01:03
|
|||
|---|---|---|---|
|
|||
Разбор процедуры по графике |
|||
|
#18+
Вот исходнывй код программы, но не хватает одной процедуры. Код взят с сайта 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 */ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=16&mobile=1&tid=1346367]: |
0ms |
get settings: |
8ms |
get forum list: |
19ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
158ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
25ms |
get tp. blocked users: |
1ms |
| others: | 297ms |
| total: | 525ms |

| 0 / 0 |
