Реализация двухмерного алгоритма отсечения прямых Коэна-Сазерленда представлена в следующих процедурах. Расширение этого алгоритма на трехмерную ситуацию очевидно, а более подробно трехмерное наблюдение рассматривается в следующей главе.

class wcPt2D { public:

GLfloat x, у;

};

inline GLint round (const GLfloat a)

{ return GLint (a + 0.5); }

/* Для каждой внешней области прямоугольного отсекающего окна

* определяется четырехбитовый код. */

const GLint winLeftBitCode = 0x1;

const GLint winRightBitCode - 0x2; const GLint winBottomBitCode = 0x4; const GLint winTopBitCode = 0x8;

/* Битовый код области также присваивается каждой конечной

* точке входного отрезка согласно его расположению

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

* отсекающего окна.

* Конечная точка с кодом области 0000 находится внутри

* отсекающего окна, в противном случае она находится вне хотя

* бы одной отсекающей границы. Если применение операции ИЛИ

* к двум кодам конечных точек дает значение 'false', вся

* линия, определенная этими двумя конечными точками

* записывается (принимается). Если применение операции И к

* двум кодам конечных точек дает значение 'true', линия лежит

* полностью вне отсекающего окна, и она исключается из

* дальнейшей обработки (отклоняется). */

inline GLint inside (GLint code) { return GLint (!code); } inline GLint reject (GLint codel, GLint code2)

{ return GLint (codel & code2); } inline GLint accept (GLint codel, GLint code2)

{ return GLint (!(codel | code2)); }

GLubyte encode (wcPt2D pt, wcPt2D winMin, wcPt2D winMax)

{

GLubyte code = 0x00; if (pt.x < winMin.x)

code = code I winLeftBitCode; if (pt.x > winMax.x)

code = code I winRightBitCode; if (pt.y < winMin.у)

code = code I winBottomBitCode; if (pt.y > winMax.у)

code = code | winTopBitCode; return (code);

}

void swapPts (wcPt2D * pi, wcPt2D * p2)

(

wcPt2D tmp;

tmp = *pl; *pl = *p2; *p2 = tmp;

}

void swapCodes (GLubyte * cl, GLubyte * c2)

{

GLubyte tmp;

tmp = *cl; *cl - *c2; *c2 = tmp;

}

void lineClipCohSuth (wcPt2D winMin, wcPt2D winMax,

wcPt2D pi, wcPt2D p2)

t

GLubyte codel, code2;

GLint done = false, plotLine = false;

GLfloat m; while (!done) {

codel = encode (pi, winMin, winMax); code2 = encode (p2, winMin, winMax); if (accept (codel, code2)) { done = true; plotLine = true;

}

else

if (reject (codel, code2)) done = true; else {

/* Пометить конечную точку вне окна на экране как pi. */ if (inside (codel)) ( swapPts (&pl, &p2); swapCodes (Scodel, &code2);

}

/* Использовать тангенс угла наклона m */

/* для расчета пересечения линии со стороной. */ if (р2.х != pl.x)

m = (р2.у - pi.у) / (р2.х - pl.x); if (codel & winLeftBitCode) {

pl.y += (winMin.х - pl.x) * m; pl.x = winMin.x;

}

else

if (codel & winRightBitCode) { pl.y += (winMax.x - pl.x) * m; pl.x = winMax.x;


⇐ вернуться назад | | далее ⇒