class Boolean: public GeomObj{ public:
GeomObj *left. *right: // pointers to the children // указатели на потомков
BooleanO {left = right - NULL:} // constructor // конструктор
virtual bool hit(Ray Sr. Intersection Sinter):
…other methods… II другие методы }: Поскольку объекты класса GeomObj имеют сферический и прямоугольный экстенты, то их имеют и Booleans, что весьма полезно, так как объекты Booleans при трассировке лучей требуют много ресурсов и хорошо все, что убыстряет эту трассировку. Мы разработаем специальную подпрограмму hit() для класса Booleans, которая «знает», как искать пересечения луча с объектами этого класса; таким образом, мы вновь используем полиморфизм для упрощения кода. Действительно, поскольку подпрограмма hit() должна оперировать с объединениями, пересечениями и разностями различным образом, то
1 Согласно тексту, на рнс. 14.60, б буквы с индексами следует заключить в квадратики, что ис сделано в оригинале (замечание для художника).
Введение в трассировку лучей
полезно для трех видов Booleans образовать отдельные классы. В соответствии с этим сформируем классы UnionBool, IntersectionBool, DifferenceBool. Определение класса UnionBool имеет следующий простой вид:
class UnionBool : public Boolean{ public:
UnionBool О {BooleanO:} // constructor // конструктор
virtual bool hitCRay Sr. Intersection Sinter):
…other methods…
}:
Остальные определения почти идентичны. Каждому типу будет соответствовать своя подпрограмма hitO, которая наилучшим образом приспособлена к его специфической природе.
Отметим, что класс Booleans не содержит собственного аффинного преобразования; оно имеется только в классе Shapes. Вследствие этого преобразования Булева дерева могут производиться только в его листьях. Такое конструкторское решение имеет как преимущества, так и недостатки, и в действительности некоторые системы моделирования и трассировщики лучей функционируют по-разному. Для того чтобы понять это различие, рассмотрим рис. 14.61, а, на котором показано дерево для Булева объекта, который имеет преобразование в каждом внутреннем узле, а также и в каждом листе. Влияние каждого преобразования «ощущается» всеми узлами «ниже его» в его поддеревьях. Как разъясняется в упражнениях, такое дерево геометрически эквивалентно дереву, изображенному на рис. 14.61, б (в том смысле, что оба дерева представляют одну и ту же форму), где преобразования «стекли» к листовым узлам и скомпоновались так, что каждый лист стал обладателем всего одного преобразования.