## Определение столкновений в наборе тел Данный способ оценки столкновений применяется в случае, когда необходимо осуществить серию тестов на столкновение для одного и того же набора тел, меняющих свое положение во времени. На рис. 1.2.1 изображен механизм, представляющий собой сборочную единицу из семи деталей, положение которых подчинено кинематическим связям. Требуется оценить границы, в пределах которых детали не мешают друг другу при работе механизма. На рис. 1 приведено положение деталей механизма, при котором возникают столкновения между ними. Красным цветом на рис. 2 показаны грани тел, встретившихся друг с другом при выходе за границы свободного движения. ```{figure} ../../pictures/R.4.2.1.png :width: 6cm :align: center Рис. 1 ``` ```{figure} ../../pictures/R.4.2.2.png :width: 6cm :align: center Рис. 2 ``` Для контроля столкновения между телами из некоторого набора необходимо завести экземпляр класса MbCollisionDetectionUtility, с помощью метода **AddItem**() добавить тела в набор для контроля столкновений. В момент времени, когда одно или несколько тел изменили положение, приложение сообщает телам набора новое положение вызовом **Reposition** и определяет, имеются ли в геометрической модели коллизии с помощью вызова **CheckCollisions**. Класс для контроля столкновений MbCollisionDetectionUtility объявлен в файле *cdet_utility.h*, вспомогательные типы данных объявлены в файле *cdet_data.h*. Метод ```cpp cdet_item MbCollisionDetectionUtility::AddItem (const MbSolid & solid, const MbPlacement3D & place, cdet_app_item appItem = CDET_APP_NULL) ``` добавляет твердое тело **solid** в набор для контроля столкновений. Входными параметрами метода являются: - **solid** -- твердотельная модель; - **place** -- локальная система координат, задающая положение тела **solid** в пространстве; - *appItem* -- геометрический объект клиентского приложения, которому принадлежит тело. Метод возвращает дескриптор объекта для контроля столкновений. Параметр *appItem* используется для идентификации объектов модели клиентского приложения при их столкновении. Если параметр *appItem* не определен, то идентификация осуществляется только на основе дескриптора (тип cdet_item), с которым тело было зарегистрировано в наборе. Предполагается, что одному объекту *appItem*, может принадлежать не одно тело MbSolid, то есть для одного и того же объекта с *appItem* метод **AddItem** может быть вызван более одного раза. В этом случае тела из группы, добавленной для одного и того же *appItem,* не проверяются на столкновения между собой. Метод ```cpp cdet_item MbCollisionDetectionUtility::RemoveItem(cdet_item cdItem) ``` удаляет твердое тело из набора для контроля столкновений. Входным параметром метода является *cdItem* -- дескриптор объекта для контроля столкновений, ранее добавленный методом **AddItem**(). Метод возвращает дескриптор объекта. Метод ```cpp cdet_result MbCollisionDetectionUtility::CheckCollisions(cdet_query cdQuery = defaultQuery) ``` проверяет столкновения между объектами из контрольного набора тел. Входным параметром метода является **cdQuery** -- структура запроса деталей столкновения. Метод возвращает код результата поиска столкновений cdet_result, который может содержать следующие коды: - CDM_RESULT_None -- результат неопределенного типа; - CDM_RESULT_NoCollisionDetected -- столкновений не выявлено: пересечений нет или поиск был прерван; - CDM_RESULT_CollisionDetected -- выявлено хотя бы одно объемное пересечение (коллизия); - CDM_RESULT_Error -- неизвестная ошибка или внутрисистемная ошибка. Метод **CheckCollisions**() ищет столкновения между телами, добавленными в контрольный набор с помощью вызова **AddItem**(). Метод вернет значение CDM_RESULT_CollisionDetected, если в данном наборе тел найдено столкновение. Если столкновений не обнаружено, то метод вернёт CDM_RESULT_NoCollisionDetected. Код cdet_result является основным результатом работы алгоритма **CheckCollisions**, однако с помощью структуры **cdQuery** можно заказать более детальную информацию о результатах поиска столкновений, а также ограничить или даже прервать поиск, когда это требуется. Если параметр **cdQuery** не определен, то алгоритм поиска не тратит время на выявление всех подробностей столкновения и останавливается, как только будет найдена первая пара пересекшихся граней. Если для одного и того же объекта cdet_app_item добавлены два и более тел, то столкновения в пределах такой группы не проверяется.