14.12. Составные объекты: логические операции с объектами
RD
.3 .4 .5 -4-1-i-
.2
-4-
.7 .8 .9 \ I-^-
.35
.6 .75 -<-Ц
.84
1.1 -4-
.3.35 .6 .7 .84 .9 1,1 Объединение I <-i I-I I I <
.2 .3 .7 .75 .9 1,1 Разность -»-I->-н-) I
.1 .2 .4 .5 .75 .8 Объединение \ <-к-<-MРис. 14.62. Пример пересекающихся записей Компоновка этих списков осуществляется посредством их просмотра, в процессе которого на каждом шаге отмечается, которому из «очередных» элементов из двух списков соответствует меньшее время соударения, а также определяется, находится ли луч перед этим очередным соударением внутри данного объекта или вне его. Эти фрагменты информации компонуются способом, соответствующим используемому оператору: объединение (union), пересечение (intersection), разность (difference). На рис. 14.62, б приведен результирующий г-список после компоновки - для каждого из Булевых операторов.
Рассмотрим специфический пример логики, используемой при компоновке списков. Предположим, что оператор - difference, а момент времени - непосредственно перед следующим временем соударения, причем луч находится внутри левого объекта и вне правого, вследствие чего он должен быть внутри разности этих объектов. Следующее время соударения исследуется в каждом из списков; предположим, что время из правого списка оказалось меньшим. Это означает, что сразу после этого следующего времени соударения луч будет находиться внутри правого объекта, поэтому сейчас он должен быть вне разности объектов. В данном примере состояние луча в составном объекте изменяется из «внутренности» во «внешность».
Состояние луча (внутри или вне объекта он находится в текущий момент времени) при прохождении его через поддеревья мы отслеживаем с помощью следующих переменных:
bool lftlnside:
// true if ray is inside left object: // true, если луч внутри левого обьекта bool rtlnside:
// true if ray is inside right object; // true, если луч внутри правого обьекта bool comblnside: