WedX - журнал о программировании и компьютерных науках

Обработка столкновений объектов в 2D-сетке

Я разрабатываю симуляцию на Java, в которой объекты перемещаются по двумерной сетке. Каждая ячейка в сетке может быть занята только одной ячейкой, и объекты перемещаются, переходя из одной ячейки в другую.

Это больше теоретически, чем специфично для Java, но есть ли у кого-нибудь идеи относительно того, как я должен подходить к обработке столкновений с этой сеткой? Существуют ли какие-либо алгоритмы, которые люди использовали для обработки столкновений в мире, похожем на сетку?

Обратите внимание, я не говорю об обнаружении столкновений, так как это тривиально, поскольку объекты перемещаются из одной ячейки в другую. Я говорю об обработке столкновений, которая может стать чрезвычайно сложной.

Пример: объект A хочет переместиться в то же место, что и объект B, а объект C хочет переместиться в текущее местоположение объекта B. Поскольку каждая ячейка может содержать только один объект, если объект A сможет переместиться в желаемое место, это приведет к тому, что объект B останется неподвижным, и, следовательно, объект C также останется неподвижным.

Можно представить, что это может создать еще более длинную цепочку коллизий, которые необходимо обработать.

Существуют ли какие-либо алгоритмы или методы, которые люди использовали, которые могут помочь в этом? Поиск этой проблемы практически невозможен без насыщения результатов поиска алгоритмами обнаружения столкновений.

Редактировать: все объекты перемещаются одновременно. Я хочу ограничить количество объектов, которые должны оставаться неподвижными, поэтому я предпочитаю сначала обрабатывать объекты с более длинными цепочками столкновений (например, объект B в этом примере).


  • Насколько я понимаю, примерная ситуация выглядит так [A]->[ ]<-[B]<-[C]. В зависимости от того, кто должен сделать первый ход A или B при условии, что C хода будут последними, вы можете получить два результата: [ ] [A] [B] [C] и [A] [B] [C] [ ]. У вас есть заказ на обработку клеток? Двигаются ли клетки одновременно? 21.02.2017
  • Ваше понимание правильное! Все объекты перемещаются в одно и то же время (только что добавил это, спасибо), и у меня нет порядка обработки ячеек (хотя я был бы готов создать какой-то порядок, если это необходимо). Приведенный мной пример не кажется слишком сложным, но вы можете себе представить сложность, если бы цепочка была расширена, например, если бы другой Объект хотел переместиться в местоположение C, а другой хотел бы переместиться в местоположение A. 21.02.2017
  • Каким будет следующее состояние такой ситуации [A]->[ ]<-[B]? Будет ли это [A] [ ] [B] (они просто останутся там, где были)? 21.02.2017
  • Если у вас будет порядок, в котором вы будете обрабатывать перемещения объектов, то проблема очень проста! Просто перебирайте список (очередь с приоритетом), обрабатывая перемещение объектов один за другим. В случае, если ячейка пытается перейти в занятую ячейку, вы можете просто проигнорировать такой ход. Таким образом, ситуация, подобная [A]->[B]->[ ], разрешится в [A] [ ] [B]. 21.02.2017
  • Но исходя из примера, который вы только что привели, что, если объект E захочет переместиться в ячейку объекта A? Столкновение между объектами A и B необходимо обработать в первую очередь, потому что результат этого перемещения определяет, сможет ли объект E переместиться в желаемое место или нет. Как мне узнать, что столкновение AB должно обрабатываться до столкновения AE? Очередь приоритетов звучит великолепно, но как мне определить приоритет каждого объекта? 21.02.2017
  • У меня есть идея. Забудьте о приоритете :). Вы можете разрешить коллизию в пользу объекта A, если у него очень длинная цепочка, верно? 21.02.2017
  • Да исправить!! Я хочу ограничить количество объектов, которые должны оставаться неподвижными, поэтому это означает, что приоритет перемещения должен быть отдан объектам с более длинными цепочками (например, A в этом примере). 21.02.2017
  • Давайте продолжим это обсуждение в чате. 21.02.2017
  • Привет, Иван, я до сих пор не могу найти пример, где ваше решение не сработает. Еще раз большое спасибо за помощь. Если вы представите очень краткое объяснение своего решения (идея построения деревьев), я буду рад отметить его как ответ. Спасибо еще раз! 21.02.2017

Ответы:


1

Согласно обсуждению с OP, объекты следует перемещать таким образом, чтобы максимизировать количество всех перемещенных объектов.

Объекты со своими ссылками образуют лес деревьев. Если объект A ссылается на ячейку, занятую объектом B, мы можем сказать, что B является родителем объекта A в дереве. Таким образом, объекты соответствуют узлам, а ссылки соответствуют ребрам в деревьях. В корне каждого дерева будет некоторая пустая ячейка (на самом деле это тот случай, когда пустая ячейка соответствует узлу). Деревья не имеют общих узлов.

Прежде чем двигаться дальше, мы должны признать, что могут быть ситуации с циклами. Как это:

[A] -> [B]                 
 ^      v       or     [A] <=> [B]
[D] <- [C]                 

Такие циклы легко идентифицировать. Некоторые объекты могут прямо или косвенно ссылаться на объекты цикла, а также формировать дерево. Цикл может происходить только в корне дерева.

Допустим, мы построили все деревья. Теперь возникает вопрос: Как мы можем разрешать коллизии? имея в виду, что мы хотим максимизировать количество перемещенных узлов. Столкновения соответствуют узлу, имеющему более 1 дочернего элемента.

В деревьях цикл-корень у нас нет другого варианта, кроме как перемещать только циклические объекты, не перемещая никакие другие объекты в дереве. Понятно, что по-другому мы не можем.

В дереве пустой корневой ячейки сначала мы должны решить, какой корневой дочерний элемент будет помещен в корневую пустую ячейку. Затем у нас появится новая пустая ячейка, где мы должны будем принять такое же решение. И так далее до листового узла. Чтобы максимизировать количество перемещенных узлов, мы должны взять самую длинную цепочку от корня до некоторого листа и переместить ее узлы. Все остальные узлы не двигаются. Это можно легко сделать, пройдя по дереву с помощью некоторой рекурсивной функции и вычислив следующую функцию f для каждого узла fleaf = 0 и >fузел = MAX(fдочерний элемент1, fдочерний элемент2, ...) + 1. Таким образом, вышеупомянутое решение заключается в выборе дочернего узла с самым большим f.

    *
   /|\
  A B C         The optimal move path  is   * <- C <- E <- H
 /   /|\
D   E F G
   /
  H
21.02.2017

2

Проверка «заблаговременно»/«следующий шаг» приведет к сложным вычислениям и даже взрывам.

Вместо этого вы можете (параллельно) использовать проверку «какая частица может двигаться в это место?» на каждую ячейку. Для этого вам понадобится карта скоростей с вектором скорости в каждой ячейке. Затем, следуя этому вектору в обратном направлении, вы замечаете ячейку. Если есть частица, попасть в клетку.

Таким образом, коллизий не происходит, потому что выполняется только 1 действие на ячейку. Просто получите ближайшую ячейку от конечной точки отрицательного вектора скорости.

Это несколько сложно вычислить, так как скорость может не попасть точно в центр ячейки. Нужна вероятность (если она очень близко к углам, чем к центру) для равенства движения / макроэффектов.

Таким образом, будет состояние гонки только для индекса ячеек, и это будет допускаться случайностью движения (или выбором частиц в зависимости от расстояния от центра ячейки).

В квантовой физике частицы могут перепрыгивать через стену, стоять на месте (даже если этого не должно быть) и делать некоторые другие вещи, которые не являются естественными для классической физики. Так что, если разрешение высокое, а скорость не выше размера карты, это должно выглядеть естественно, особенно со случайностью, когда несколько ячеек конкурируют за получение частицы из другой ячейки.

Несколько проходов:

  • рассчитать, какие ячейки нужно собрать из каких ячеек,
  • рассчитать вероятности, а затем выигрышные ячейки
  • ячейки выигрыша собирают свои частицы из исходных ячеек параллельно.
  • (не рекомендуется), если все еще есть не выбранные частицы со скоростью, то выполнение вычислений для каждой частицы для их перемещения (если их целевая ячейка пуста) должно еще больше уменьшить стационарные частицы.
  • рассеять скорости частиц по ячейкам несколько раз (используя 2D-трафарет), которые будут использоваться в следующей итерации (это легко обрабатывает сложные расчеты столкновений и смущающе параллельным способом, хорошо подходит для многопоточности-gpgpu) (если частицы могут двигаться только ближайшим соседям, это также помогает узнать, какой из них, даже без какого-либо приоритета или вероятности, поскольку каждая ячейка изгибает скорости соседних ячеек с помощью диффузии скоростей)

проверить Гаусса-Зейделя (https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method) для решения многих линейных уравнений.

вычисления выполняются на ячейках, а не на частицах, поэтому границы карты будут неявно пуленепробиваемыми, а вычисления могут быть равномерно распределены между всеми ядрами.


Пример:

частица А падает

частица B движется вправо

они на пути к столкновению

решить для состояния равновесия карты скорости (Гаусс-Зейдель)

теперь ячейка частицы А имеет скорость вниз+вправо

то же, что Б

как будто они столкнулись, но они все еще на своих ячейках.

Перемещение их со скоростью их клеток заставит их выглядеть так, как будто они находятся в столкновении.

21.02.2017
Новые материалы

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


Для любых предложений по сайту: [email protected]