В процессе разбиения области могут стать чрезвычайно малыми. Как же мы решим, что область достаточно мала и ее дальнейшее разбиение запрещено? Области определены в порту просмотра, поэтому применим следующий простой принцип точности по изображению: когда область уже разбита так мелко, что она содержит только один центр пиксела, то больше ее разбивать нельзя, даже если она не является простой. Вместо разбиения мы определим грань для рисования с помощью проверки глубин всех граней, втянутых в эту область, из которых найдем ближайшую. Тогда пикселу присваивается цвет этой грани. Если же область мала настолько, что не содержит ни одного центра пиксела, то она игнорируется.

Листинг 13.5. Скелет класса для поддержки алгоритма Варнока

class Region{ public:

Rect г: // a region is a rectangle // прямоугольная область

int getSizeO: // how big is it? // каковы ее размеры?

boo! isSimple_DrawIt(FaceListS faces): // if it's simple, draw it // если она простая, то рисуем ее

void drawClosestFaceCFaceListS faces):

boo! isInvolvedCFaceS face): // is the region involved with face? // есть ли грань, втянутая в область?

int buildQuadrants(Regions nw. Regions ne. Regions sw. Regions se):

void draw(FaceListS faces) // the main drawing method // основной метод рисования

{

int size = getSizeO: // how big is it? // каковы размеры области?

if(size < Dreturn: // nothing to draw // рисовать нечего

if(size -» 1) drawClosestFace(faces): // covers one pixel center // покрывает один центр пиксела

else if(isSimple_drawIt(faces))return: // draw it and exit // рисуем область и выходим

else

// it's not simple enough // область недостаточно проста {

Region Nw. NE. Sw. SE:

buildQuadrants(Nw. NE. SW. SE): // make subregions // создаем подобласти

NW.draw(faces): // draw each of them // рисуем каждую из них

13.5. Методы разбиения области

NE.draw(faces): Sw.drawCfaces): SE.draw(faces):
}
}
}:

Для реализации алгоритма Варнока определим класс Region, как предлагается в листинге 13.5, и зададим в нем ряд методов. Основным методом здесь является draw(FaceList&faces), который рисует обрабатываемую область. Его параметром является список всех граней в сцене, представленный в некотором подходящем типе данных Fi 1 el ist. Подпрограмма drawO использует метод getSizeO для проверки того, сколько центров пикселов содержится в области region. Если нет ни одного, то ничего не делается. Если имеется ровно один центр пиксела, то подпрограмма drawClosestFaceO проверяет глубины всех втянутых в центр этого пиксела граней и устанавливает в качестве цвета этого пиксела цвет ближайшей грани. Если присутствует более одного пиксела, то метод isSimpl e_drawlt( ) проверяет, проста ли эта область, и если да, то рисует ее. В противном случае формируются четыре подобласти и метод drawO вызывает сам себя для каждой из этих областей.


⇐ Предыдущая| |Следующая ⇒