В листинге 14.18 приведен псевдокод для метода DifferenceBool :: hit(), чтобы проиллюстрировать процесс компоновки списков.
Листинг 14.18. Метод hit() для класса DifferenceBool
bool DifferenceBool:: hitCRay Sr. Intersection Sinter) {
Intersection lftlnter. rtlnter:
lftInter.numHits - rtlnter.numHits - 0: // initially // начальные значения
if(ray misses extents) return false: // луч проходит мимо экстентов // early out? // досрочный выход?
if(!left->hit(r.lftlnter))return false:
GeomObj* leftObject - lftlnter.hit[0].hitObject: // may need this later // это может понадобиться позднее
if(!right->hit(r.rtlnter))
{
inter - lftlnter: // right tree has no effect // правое дерево не дает эффекта
return true:
// early out // досрочный выход }
// combine the lists. Initial states: // компонуем списки. Начальные состояния:
bool lftlnside = KlftInter.hit[0].isEntering): // initial insideness // начальная «внутренность»
bool rtlnside = !(rtlnter.hit[0].isEntering):
bool comblnside = lftlnside && Irtlnside // for the difference
14.12. Составные объекты: логические операции с объектами
// для разности
// go through lists until one has been consumed
// просматриваем списки, пока один из них не исчерпается
int iL =0. iR - 0. iC - -1:
Hitlnfo nextHit:
whileUiL < lftlnter.numHits) && (iR < rtlnter.numHits)) {
// while both lists are nonempty
// пока оба списка не пусты ,
bool newlnside: // the new result state // новое результирующее состояние
if(lftInter.hit[iL].hitTime <- rtInter.hit[iR].hitTime)
{
nextHit - lftInter.hit[iL++]:
// grab left item: // берем левый элемент
lftlnside - !lftlnside; // state is reversed by hit
// при соударении состояние изменяется на противоположное
newlnside - lftlnside && Irtlnside; // state after the hit // состояние после соударения
leftObject - nextHit.hitObject; // needed when exiting right tree // понадобится при выходе из правого дерева
if(newlnside !- comblnside) // has result state changed? // изменилось ли результирующее состояние?