Заставить многокомпонентное "жидкое тело" действовать как единое тело

Я использую 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 силы (я считаю, что существует)?
  • Должен ли я использовать пружины, чтобы соединить все маленькие тела? ( пружины)
  • Как бы мне всегда получить "центр тела"?

Благодарю.

1 ответ

Решение

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

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


Симуляция

Во-первых, давайте поговорим о симуляции, которую вы показали. Вы пишете "текучие тела", но из того, что я вижу в примере кода, нет ничего текучего - это симуляция чистых частиц с "обманутыми" физическими особенностями, которая вытекает из (1) автоматического демпфирования частиц и (2) восстановления что в норме означает, насколько упругое столкновение с объектом (например, 0.8 значение в этом случае означает, что 20% кинетической энергии теряется при каждом столкновении). В общем, у нас есть моделирование частиц с большим количеством демпфирования.

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

Ваши вопросы

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

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

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

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

Если 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, добавив трение в пример симуляции, должно быть легко.

Другие вопросы по тегам