Последовательная реализация алгоритма отсечения многоугольников Сазерленда-Ходгмана демонстрируется в следующем наборе процедур. Входной набор вершин преобразуется в выходной путем применения процедур отсечения слева, справа, снизу и сверху.

typedef enum { Left, Right, Bottom, Top } Boundary; const GLint nClip = 4;

GLint inside (wcPt2D p, Boundary b, wcPt2D wMin, wcPt2D wMax)

{ switch (b) {

case Left: if (p.x < wMin.x) return (false); break;

case Right: if (p.x > wMax.x) return (false); break;

case Bottom: if (p.y < wMin.y) return (false); break;

case Top: if (p.y > wMax.y) return (false); break; }

return (true);

}

GLint cross (wcPt2D pi, wcPt2D p2, Boundary winEdge,

wcPt2D wMin, wcPt2D wMax)

{

if (inside (pi, winEdge, wMin, wMax) == inside (p2, winEdge, wMin, wMax)) return (false); else return (true);

}

wcPt2D intersect (wcPt2D pi, wcPt2D p2, Boundary winEdge,

wcPt2D wMin, wcPt2D wMax)

{

wcPt2D iPt;

GLfloat m;

if (pl.x != p2.x) m = (pl.y - p2.y) / (pl.x - p2.x); switch (winEdge) { case Left:

iPt.x = wMin.x;

iPt.y = p2.y + (wMin.x - p2.x) * inbreak; case Right:

iPt.x = wMax.x;

iPt.y = p2.y + (wMax.x - p2.x) * m; break; case Bottom:

iPt.y = wMin.y;

if (pl.x != p2.x) iPt.x = p2.x + (wMin.y - p2.y) / m; else iPt.x = p2.x; break; case Top:

iPt.y = wMax.y;

if (pl.x != p2.x) iPt.x = p2.x + (wMax.y - p2.y) / m;

else iPt.x = p2.x;

break;

}

return (iPt) ;

}

void clipPoint (wcPt2D р, Boundary winEdge, wcPt2D wMin, wcPt2D wMax, wcPt2D * pOut, int * cnt, wcPt2D * first[], wcPt2D * s)

<

wcPt2D iPt;

/* Если для данной границы отсечения не существует

* предыдущей точки, записывается текущая точка.

*/

if (!first[winEdge]) first[winEdge] = &p; else

/* Предыдущая точка существует. Если отрезок, соединяющий р

* и предыдущую точку, пересекает данную границу отсечения,

* находится точка пересечения. Если еще есть границы,

* отсечение по которым не выполнялось, провести отсечение

* по ним. Если границ отсечения больше нет, точки пересечения

* добавляются в выходной список.

*/

if (cross (р, s[winEdge], winEdge, wMin, wMax)) {

iPt = intersect (p, s[winEdge], winEdge, wMin, wMax); if (winEdge < Top)

clipPoint (iPt, b+1, wMin, wMax, pOut, cnt, first, s); else {

pOut[*cnt] = iPt; (*cnt)++;

}

}

/* Для данной границы отсечения записать р как новую

* точку.

*/

s[winEdge] = р;

/* Если точка внутренняя, перейти к следующей необработанной

* границе (если такие остались).


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