Почему моя вода взрывается?
Я пытаюсь реализовать метод Клаве для моделирования жидкостей в JavaScript, поэтому отладка - это кошмар, поэтому я спрашиваю здесь, надеясь, что кто-то, кто прошел через то же самое, скажет мне, что я делаю неправильно.
Пока у меня все работает нормально:
Но у меня есть две проблемы:
1) Поскольку в этом методе все "смещено" на полшага, я не уверен, как правильно отразить частицы от стенок. Прямо сейчас я беру позицию частицы и предыдущую позицию и переворачиваю их вокруг пересеченной стены, затем масштабирую вокруг точки пересечения с помощью коэффициента отскока.
Моя логика говорит мне, что это должно работать. Следующим шагом в алгоритме является обновление скоростей частиц, поэтому я также отражаю предыдущую позицию. Но на практике это дает мне результат, которого я не понимаю:
Это показывает "силы" на частицы. Стены отражают слишком много силы, которая держит все в постоянном движении.
Формула 4.58 в этой статье, по- видимому, показывает способ предотвратить это, но я не смог заставить ее работать.
Также в статье есть вещи, которые я не получаю, например, что означает "мы хотим отражать только скорость, которая была опущена при столкновении". Зачем? Может ли кто-нибудь ELI5 этот материал для меня, пожалуйста?
2) Даже когда стены не задействованы, симуляция периодически "взрывается". Это происходит чаще при более высоком давлении:
Это JavaScript, так что это так, но я просмотрел код, и нет делений на ноль или ситуаций, в которых я могу представить, что происходит NaN.
Я видел некоторые разговоры в газетах о нестабильности симов, и мне интересно, так ли это. Большая часть того, что есть в этой литературе, выше моего понимания.
Из того, что я понял (я думаю), один из способов устранения нестабильности - это вязкость, но я добавил ее, и это не помогло со взрывами:
Я могу опубликовать код, но на первом этапе работы это довольно сложно читать прямо сейчас.
Последний вопрос: как мне выяснить, как преобразовать псевдоконстанты в этом методе в физические единицы?
Редактировать: Я обнаружил, что сим иногда зависает, кажется, он где-то производит NaN, но Chrome ловит его слишком поздно.
2 ответа
Предполагая, что это проект cg без строгого физического значения...
Во-первых, вам действительно следует рассмотреть возможность использования фиксированного временного шага для кода симуляции, в противном случае вы получите неустойчивое (и визуально мешающее) поведение, поскольку dt (и ошибка) колеблются вокруг. Если вы не можете получить постоянную частоту кадров в соответствии с вашими конечными требованиями, позиции следует интерполировать, а не моделировать в не фиксированные моменты времени.
Что касается ваших расчётов стен, то это явно зависит от того, какого эффекта вы хотите достичь; поэтому, если вы примените более или менее сохраняющее импульс зеркальное состояние (как вы это делаете сейчас), частицы будут продолжать "циркулировать" вокруг, даже если применяется демпфирование. Если вы хотите, чтобы жидкость как-то "прилипала" к стенам, вам нужно ввести силы на стену или какой-то другой более сильный рассеивающий эффект.
Я запустил ваш код, и после установки постоянного dt и настройки вязкости и упрощения расчета стен до более простого "if (p.px
Очевидно, здесь много всего. Я уверен, что не могу ответить на все это, но вот некоторые, надеюсь, важные моменты:
О стенах: то, что вы реализовали, называется импульсным зеркалом. В жидкости, находящейся под давлением, импульсное зеркало служит для привлечения частиц с отрицательным поверхностным натяжением (потому что за его пределами нет частиц, способных отталкивать частицы вблизи границы). Более плотно упакованные частицы будут генерировать большие силы и с большей вероятностью вызовут численные проблемы (особенно потому, что их телепортация имеет тенденцию давать им потенциальную энергию).
О коэффициенте восстановления: простое линейное масштабирование вокруг столкновения создает тангенциальную силу при ударе, которая не характерна для импульсных зеркал, но имеет тенденцию создавать физически реалистичное условие скольжения.
О второй статье, которую вы связали: я думаю, что они пытаются сделать что-то умное, основываясь на своей точечной проекции. Однако я не знаю, почему они просто проецируются обратно на поверхность (вместо того, чтобы вычислять время столкновения и затем новую позицию, основанную на (уменьшенной) новой скорости после этого).