Пространственные структуры данных для движущихся объектов?
Мне было интересно, какая лучшая структура данных для работы с множеством движущихся объектов (сферы, треугольники, ящики, точки и т.д.)? Я пытаюсь ответить на два вопроса: обнаружение Nearest Neighbor и Collsion.
Я понимаю, что традиционно структуры данных, такие как деревья R, используются для запросов ближайшего соседа, а Oct/Kd/BSP используются для задач обнаружения столкновений со статическими объектами или с очень немногими движущимися объектами.
Я просто надеюсь, что есть что-то еще, что лучше.
Я ценю всю помощь.
Ответы
Ответ 1
-
Вы можете разделить сцену в октете и использовать согласованность сцены. Ваш движущийся объект, который вы тестируете, будет находиться в определенном node дерева для определенного количества кадров в зависимости от его скорости. Это означает, что вы можете предположить, что оно будет в node и поэтому быстро вырезает много объектов, которые не находятся в node. Конечно, сложный бит - это когда ваш объект близок к краю вашего раздела, вам нужно будет убедиться, что вы обновляете node объект.
-
Движущийся объект имеет направление и скорость. Вы можете легко разделить сцену на две части, используя перпендикулярное разделение от направления движения объектов. Любой объект с неправильной стороны этого раздела не нужно проверять. Конечно, компенсируйте другую скорость объекта. Поэтому, если другой объект является разумным медленным, вы можете легко вырезать его из дальнейших проверок.
-
Всегда упрощайте любую фигуру, которую вы тестируете, с помощью рамки с выравниванием по оси. Начальный тест столкновения
-
Вы можете взять расстояние между вашим объектом и другим движущимся объектом плюс скорости. Если другой движущийся объект движется в одном и том же общем направлении с большей скоростью, вы можете устранить его из проверки.
-
Существует множество других оптимизаций в зависимости от формы объекта. Круги или квадраты или более сложные формы имеют определенную оптимизацию, которую вы можете делать во время перемещения.
-
Предполагая, что некоторые объекты останавливаются или могут перестать двигаться, вы можете отслеживать остановленные объекты. эти объекты могут быть обработаны как статические объекты, и поэтому проверки выполняются быстрее, и вы можете применить к ним все методы статической оптимизации.
-
Я знаю больше, но не могу думать ни о чем с моей головы. Не делайте этого некоторое время.
Теперь, конечно, это зависит от того, как вы делаете обнаружение столкновений. Вы постепенно обновляете позицию объекта на основе скорости и проверяете, как будто она статична. Или вы компенсируете скорость, выдавливая форму и вычисляя начальные точки столкновения. Первый требует небольшого шага для быстро движущегося объекта. Последнее сложнее и дорого, но дает лучшие результаты. Также, если у вас есть вращающиеся объекты, тогда все становится немного сложнее.
Ответ 2
Ограничивающие сферы, вероятно, помогут вам со многими движущимися объектами; вы вычисляете квадрат радиуса объекта и отслеживаете его из центра. Если квадрат расстояния между центрами двух объектов меньше суммы квадратов радиусов двух объектов, то у вас есть потенциальное столкновение. Все сделано с квадратными расстояниями; нет квадратных корней.
Вы можете сортировать ближайших соседей по минимальному квадрату расстояния между вашими объектами. Разумеется, обнаружение столкновения может быть сложным, и с объектами, не имеющими сферической формы, Bounding Spheres не обязательно будет получать информацию о столкновении, но это может сократить ваше дерево объектов, которое вам нужно сравнить для столкновения довольно хорошо.
Вам понадобится, конечно, отслеживать ЦЕНТР вашего объекта; и в идеале вы хотели бы, чтобы каждый объект был жестким, чтобы избежать необходимости пересчитывать размеры ограниченной сферы (хотя перерасчет не является особенно сложным, особенно если вы используете дерево жестких объектов, каждый со своей собственной ограничивающей сферой для объектов, которые являются нежесткими, но они усложняются).
В принципе, чтобы ответить на ваш вопрос о структурах данных, вы можете сохранить все свои объекты в главном массиве; У меня будет набор "региональных" массивов, которые состоят из ссылок на объекты в главном массиве, которые вы можете сортировать объекты быстро, основываясь на их декартовых координатах; массивы "региона" должны иметь перекрытие, определенное, по крайней мере, из 2x наибольшего радиуса объекта в вашем массиве основных объектов (если это возможно, вопрос о масштабировании сферической сферы по сравнению с количеством объектов явно появляется).
Как только вы получите это, вы можете выполнить быстрый тест на столкновение, сравнивая расстояния всех объектов внутри региона друг с другом; опять же, это определение региона становится важным, потому что вы делаете значительный компромисс между количеством регионов и количеством сравнений. Однако это немного проще, потому что ваши сравнения расстояний сводятся к простым вычитаниям (и абс(), конечно).
Конечно, тогда вам нужно сделать фактическое обнаружение столкновений между вашими сферическими объектами, и это может быть нетривиальным, но вы значительно уменьшили количество возможных сравнений в этой точке.
В принципе, это двухуровневая система; первым является массив областей, в котором вы делаете грубую сортировку на своей сцене. Во-вторых, у вас есть расстояние между регионами; в котором вы собираетесь выполнять базовое обнаружение столкновений и помехи столкновения на объектах, которые столкнулись.
Вероятно, в этом типе алгоритма используется пространство для использования деревьев в динамической области, чтобы выравнивать размеры вашего региона, чтобы гарантировать, что ваш размер региона не будет слишком быстро расти с "переполненными" регионами; тем не менее, это нетривиально, потому что с объектами разного размера ваш вид по плотности становится... сложным, если не сказать меньше.
Ответ 3
Одним из интересных методов для обнаружения столкновений является использование аксиально выровненных ограничивающих прямоугольников (AABB), организованных в специальной структуре октетов. AABB помогает, потому что они делают очень грубые вычисления столкновений, потому что вам нужно выполнить до 6 сравнений.
Есть несколько трюков, которые вы должны использовать с octree-структурой:
1) Ограничительная область, в которой находится a node, должна быть в два раза больше, чем для обычного окта (где octree разбивает пространство без перекрытия). Поскольку каждый node должен перекрывать половину области соседних узлов. Поскольку AABB может принадлежать только одному node, этот дополнительный размер и перекрытие позволяют ему оставаться в одном node в течение более длительного периода времени.
2) Также в каждом node - и, возможно, на каждом уровне иерархии - вы сохраняете ссылки на сокеты node. Это будет связано с большим количеством дополнительного кода, но это позволит вам перемещать элементы между узлами в течение времени O (1), а не O (2logn).
Если октет занимает слишком много памяти, вы можете изменить его, чтобы использовать разреженную октетную структуру, сохраняя только дерево для частей игрового мира, на котором фактически были сущности. Однако это означало бы, что вам придется выполнять больше вычислений для каждого кадра, когда сущности перемещаются по всему миру.
Некоторые другие идеи, которые вы можете попробовать вместо октетов, - использовать kd-дерево (я считаю, что правильное имя) или использовать AABB для построения структуры снизу вверх.
Деревья KD (из памяти) разделяют пространство с помощью плоскостей, выровненных по оси, поэтому они хорошо подходят для использования с AABB.
Другая идея заключается не в том, чтобы форсировать генерацию октетов сверху вниз (начиная с коробки, envoloping по всему миру), вы создаете ее из базовых объектов и создаете более крупный AABB, которые растут, пока самый большой из них не охватит весь мир, Хотя я не уверен, как это будет работать со многими быстро движущимися объектами.
(Прошло некоторое время с тех пор, как я сделал такое пространственное кодирование разработки игр).
Ответ 4
развертка и обрезка широкой фазы + узкая фаза gjk
Ответ 5
RDC может быть полезен, особенно если ваши объекты разрежены (не так много пересечений).