Новосибирский Государственный Технический Университет. Факультет автоматики и вычислительной техники Кафедра вычислительной техники (специальность 220100). учебное пособие
Вид материала | Учебное пособие |
0.18.2 V_SetRclip - установить прямоугольник отсечения 0.18.3 V_GetRclip - опросить прямоугольник отсечения 0.18.4 V_CSclip - отсечение Коэна-Сазерленда |
- Новосибирский Государственный Технический Университет. Факультет автоматики и вычислительной, 1650.9kb.
- Рабочая программа для специальности: 220400 Программное обеспечение вычислительной, 133.96kb.
- Государственный Технический Университет. Факультет: Автоматики и Вычислительной Техники., 32.46kb.
- Образования Республики Молдова Колледж Микроэлектроники и Вычислительной Техники Кафедра, 113.64kb.
- Постоянное развитие и углубление профессиональных навыков в области информационных, 54.56kb.
- «Программное обеспечение вычислительной техники и автоматизированных систем», 1790.14kb.
- Задачи дисциплины: -изучение основ вычислительной техники; -изучение принципов построения, 37.44kb.
- Лекция №2 «История развития вычислительной техники», 78.1kb.
- Система контроля и анализа технических свойств интегральных элементов и устройств вычислительной, 582.84kb.
- Московский государственный инженерно-физический институт (технический университет), 947.05kb.
0.18.2 V_SetRclip - установить прямоугольник отсечения
/*------------------------------------------------- V_SetRclip
* Устанавливает прямоугольное окно отсечения
* Возвращает 0/1 - нет/есть ошибки в задании окна
*/
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 */
0.18.3 V_GetRclip - опросить прямоугольник отсечения
/*------------------------------------------------- V_GetRclip
* Возвращает текущее прямоугольное окно отсечения
*/
void V_GetRclip (xleft, ybottom, xright, ytop)
float *xleft, *ybottom, *xright, *ytop;
{
*xleft= Wxlef; *ybottom= Wybot;
*xright= Wxrig; *ytop= Wytop;
} /* V_GetRclip */
0.18.4 V_CSclip - отсечение Коэна-Сазерленда
/*--------------------------------------------------- V_CSclip
* Реализует алгоритм отсечения Коэна-Сазерленда с
* кодированием концов отсекаемого отрезка
*
* int V_CSclip (float *x0, float *y0, float *x1, float *y1)
*
* Отсекает отрезок, заданный значениями координат его
* точек (x0,y0), (x1,y1), по окну отсечения, заданному
* глобальными скалярами Wxlef, Wybot, Wxrig, Wytop
*
* Конечным точкам отрезка приписываются коды,
* характеризующие его положение относительно окна отсечения
* по правилу:
*
* 1001 | 1000 | 1010
* -----|------|-----
* | Окно |
* 0001 | 0000 | 0010
* -----|------|-----
* 0101 | 0100 | 0110
*
* Отрезок целиком видим если оба его конца имеют коды 0000
* Если логическое И кодов концов не равно 0, то отрезок
* целиком вне окна и он просто отбрасывается.
* Если же результат этой операции = 0, то отрезок
* подозрительный. Он может быть и вне и пересекать окно.
* Для подозрительных отрезков определяются координаты их
* пересечений с теми сторонами, с которыми они могли бы
* пересечься в соответствии с кодами концов.
* При этом используется горизонтальность и вертикальность
* сторон окна, что позволяет определить одну из координат
* без вычислений.
* Часть отрезка, оставшаяся за окном отбрасывается.
* Оставшаяся часть отрезка проверяется на возможность его
* принятия или отбрасывания целиком. Если это невозможно,
* то процесс повторяется для другой стороны окна.
* На каждом цикле вычислений конечная точка отрезка,
* выходившая за окно, заменяется на точку, лежащую или на
* стороне окна или его продолжении.
*
* Вспомогательная процедура Code вычисляет код положения
* для конца отрезка.
*
*/
static float CSxn, CSyn; /* Координаты начала отрезка */
static int CScode (void) /* Определяет код точки xn, yn */
{ register int i;
i= 0;
if (CSxn < Wxlef) ++i; else
if (CSxn > Wxrig) i+= 2;
if (CSyn < Wybot) i+= 4; else
if (CSyn > Wytop) i+= 8;
return (i);
} /* CScode */
int V_CSclip (x0, y0, x1, y1)
float *x0, *y0, *x1, *y1;
{
float CSxk, CSyk; /* Координаты конца отрезка */
int cn, ck, /* Коды концов отрезка */
visible, /* 0/1 - не видим/видим*/
ii, s; /* Рабочие переменные */
float dx, dy, /* Приращения координат*/
dxdy,dydx, /* Наклоны отрезка к сторонам */
r; /* Рабочая переменная */
CSxk= *x1; CSyk= *y1;
CSxn= *x1; CSyn= *y1; ck= CScode ();
CSxn= *x0; CSyn= *y0; cn= CScode ();
/* Определение приращений координат и наклонов отрезка
* к осям. Заодно сразу на построение передается отрезок,
* состоящий из единственной точки, попавшей в окно
*/
dx= CSxk - CSxn;
dy= CSyk - CSyn;
if (dx != 0) dydx= dy / dx; else {
if (dy == 0) {
if (cn==0 && ck==0) goto out; else goto all;
}
}
if (dy != 0) dxdy= dx / dy;
/* Основной цикл отсечения */
visible= 0; ii= 4;
do {
if (cn & ck) break; /* Целиком вне окна */
if (cn == 0 && ck == 0) { /* Целиком внутри окна */
++visible; break;
}
if (!cn) { /* Если Pn внутри окна, то */
s= cn; cn= ck; ck= s; /* перестить точки Pn,Pk и */
r=CSxn; CSxn=CSxk; CSxk=r; /* их коды, чтобы Pn */
r=CSyn; CSyn=CSyk; CSyk=r; /* оказалась вне окна */
}
/* Теперь отрезок разделяется. Pn помещается в точку
* пересечения отрезка со стороной окна.
*/
if (cn & 1) { /* Пересечение с левой стороной */
CSyn= CSyn + dydx * (Wxlef-CSxn);
CSxn= Wxlef;
} else if (cn & 2) { /* Пересечение с правой стороной*/
CSyn= CSyn + dydx * (Wxrig-CSxn);
CSxn= Wxrig;
} else if (cn & 4) { /* Пересечение в нижней стороной*/
CSxn= CSxn + dxdy * (Wybot-CSyn);
CSyn= Wybot;
} else if (cn & 8) { /*Пересечение с верхней стороной*/
CSxn= CSxn + dxdy * (Wytop-CSyn);
CSyn= Wytop;
}
cn= CScode (); /* Перевычисление кода точки Pn */
} while (--ii >= 0);
if (visible) {
out: *x0= CSxn; *y0= CSyn;
*x1= CSxk; *y1= CSyk;
}
all:
return (visible);
} /* V_CSclip */