Вы пытаетесь столкнуть движущийся выпуклый многоугольник (ваш «ромб») с другим движущимся выпуклым многоугольником, верно? Что-то вроде этого:
Ваш первый шаг должен состоять в том, чтобы преобразовать задачу в эквивалентную, в которой один из полигонов является стационарным:
Затем вы можете преобразовать движущийся многоугольник в «вал», который покрывает область, охватываемую движущимся многоугольником. Это легко сделать: если у исходного многоугольника n сторон, то у вала есть n + 2 стороны, причем две дополнительные стороны имеют ту же длину и направление, что и исходный многоугольник. вектор движения. Вы найдете, куда вставить эти новые стороны, отсортировав вершины в соответствии с их компонентами, которые ортогональны вектору движения, и вставив новые стороны в максимумы.
Теперь вы свели проблему к статическому полигону против статического полигона. Взгляните на удобную таблицу алгоритмов коллизий, предоставленную realtimerendering.com, и следуйте ссылкам , мы видим, что нам нужно использовать тест разделительной оси, например, как описано в разделе 3 эта статья Дэвида Эберли.
В двух измерениях два выпуклых многоугольника не пересекаются, если мы можем найти разделяющую ось, линию, такую, что один многоугольник приходится на одну сторону линии, а другой многоугольник — на другую:
Если нам задано направление, мы можем легко обнаружить, существует ли разделяющая ось, которая проходит в этом направлении, спроецировав два многоугольника на линию, идущую перпендикулярно этому направлению, и посмотрев, не пересекаются ли эти проекции:
Откуда мы знаем, в каком направлении пойдет разделяющая ось? Итак, если существует любая разделяющая ось, то есть ось, которая проходит параллельно одной из сторон одного из выпуклых многоугольников (см. Eberly, стр. 3). Таким образом, нужно проверить только небольшой набор направлений, и если вы проверили их все, не найдя разделяющую ось, то два многоугольника пересекаются (и, следовательно, исходные движущиеся объекты сталкиваются).
Есть много улучшений и оптимизаций, которые вы можете сделать, конечно, не ограничиваясь этим:
- Прежде чем выполнять полный тест движущегося многоугольника/многоугольника, выполните более простой тест, такой как круг/круг, чтобы вы могли быстро отклонить простые случаи.
- Используйте какую-нибудь схему пространственного разделения, такую как quadtrees, чтобы тестировать только те объекты, которые находятся достаточно близко, чтобы они могли столкнуться.
- «Кэширование свидетелей» — если линия разделяет два объекта в момент времени t, вполне вероятно, что она продолжает разделять их и в момент времени t + δ, поэтому стоит запомнить разделяющую ось, которую вы нашли, и попробуйте сначала в следующий раз (см. Rabbitz, "Быстрое обнаружение столкновений движущихся выпуклых многогранников" в Graphics Gems IV).
Но не слишком беспокойтесь об оптимизации: сначала сделайте все правильно, будучи уверенными, что позже вы сможете ускорить ее.
person
Gareth Rees
schedule
19.11.2010