Заставьте жидкое тело, состоящее из нескольких частей, действовать как единое тело

Я использую Phaser.js и его физику p2, чтобы смоделировать, что такое «жидкие тела». В этом примере видно, что создается своего рода жидкое тело (кредиты Джону Ватсону). Единственное возможное взаимодействие — движение мыши.

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

// Add a force that slows down the droplet over time
   droplet.body.damping = 0.3;

// Add bounciness and gravity
   this.game.physics.p2.restitution = 0.8;
   this.game.physics.p2.gravity.y = 250;

После некоторых исследований и размышлений я пришел к выводу, что тело, которое я ищу, должно быть более цельным, чем тело-пример, а это означает, что в определенных пределах должна быть приложена сила с направлением центра тела (центр + - вершина тела). всем «маленьким телам», из которых состоит тело. Я предполагаю, что после достижения этого, даже если я буду двигать все тело с курсорами, оно будет двигаться все вместе. Общий эффект, который я хочу, - это форма тела ворсового типа (меньшая масса в верхней части и большая масса в нижней части): базовая иллюстрация

Единственным способом для тела потерять массу должно быть внешнее усилие, приложенное к телу, которое превосходит силу сопротивления, удерживающую тело единым.

Даже после долгого изучения я, кажется, очень потерялся в этом вопросе...

  • Должен ли я буквально выбрать силы p2 (я верю, что они существуют)?
  • Должен ли я использовать пружины для соединения всех маленьких тел? (пружины)
  • Как мне всегда получать «центр тела»?

Спасибо.


person DigitalEvolution    schedule 02.11.2016    source источник


Ответы (1)


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

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


Моделирование

Во-первых, давайте поговорим о симуляции, которую вы показали. Вы пишете «жидкие тела», но из того, что я вижу в примере кода, нет ничего текучего — это чистая симуляция частиц с «обманутыми» физическими функциями, которые происходят из (1) автоматического демпфирования частиц и (2) < href="https://en.wikipedia.org/wiki/Coefficient_of_restitution" rel="nofollow noreferrer">восстановление, которое в обычном языке означает, насколько эластично столкновение с объектом (например, значение 0.8 в этом случай означает, что 20% кинетической энергии теряется при каждом столкновении). В общем, у нас есть симуляция частиц с большим количеством демпфирования.

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

Ваши вопросы

Должен ли я буквально выбрать силы p2 (я верю, что они существуют)?

На самом деле я не уверен, что это значит, но я предполагаю, что это связано с Phaser.

Должен ли я использовать пружины для соединения всех малых тел? (пружины)

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

Если x_cm — это положение (вектор) центра масс, а x[i] — это положение частицы i, то одним из примеров может быть:

F(i) = F_constant*(x_cm - x[i])

Чисто линейная функция. F_constant — некоторый (постоянный) коэффициент. Частицы, находящиеся далеко, получат большую силу, чем частицы поблизости. Затем вы вычислите эту силу для всех частиц и примените ее соответствующим образом.

Как мне всегда получать «центр тела»?

Центр масс тела вычисляется прямо вперед. В псевдокоде это выглядит так:

var x_cm
var total_mass = 0
for each particle p:
    total_mass += p.mass()
    x_cm += p.mass()*p.position()
x_cm /= total_mass

Формулы сложно отобразить здесь красиво, но это точно так же, как описано в википедии.


Еще один вариант

Этот ответ уже длинный, но просто завершающая мысль. С моей точки зрения, это звучит так, как будто вы хотите что-то похожее на песок (т. е. это симуляция частиц, похожая на ту, которую вы показали, но она также накапливается). Обычный способ имитации песка — точное моделирование, как описано выше, но с добавлением трения к частицам. Возможно ли это сделать с помощью Phaser, я не знаю, но я ожидаю, что это будет легко сделать.


РЕДАКТИРОВАТЬ: В последнем предложении была опечатка. Моделирование песка с помощью Phaser путем добавления трения к моделируемому примеру должно быть простым.

person pingul    schedule 03.11.2016
comment
Привет. Прошло уже некоторое время с тех пор, как вы ответили. Кстати, это был отличный ответ. До сих пор у меня не было возможности спросить, чего я хочу. Ну я понял вашу логику (я не профи в физике, но думаю понял). Одна из трудностей, с которыми я сталкиваюсь, заключается в том, чтобы перевести это в код... Это не имеет большого отношения к самому вопросу, но, поскольку вы очень хорошо ответили на него, я подумал, что вы можете привести меня куда-нибудь. Как вы манипулируете физическими силами, например, в программировании... Я бы предположил, что кто-то уже сделал эту работу, и я буду взаимодействовать с ней? Я не уверен, достаточно ли я ясно выразился - person DigitalEvolution; 07.11.2016
comment
@Tojó Посмотрите на функцию GameState.prototype.update в вашей ссылке. Там вы видите, что они меняют droplet.body.velocity. Чтобы перейти от силы к скорости, помните, что F = m*a и a = v*∆t --> v = F/(m*∆t). То есть, если вы вычислите некоторую силу F, вы найдете соответствующее изменение скорости, разделив силу на массу частицы и время, прошедшее с момента последнего обновления. - person pingul; 08.11.2016