Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Идеи и творения

Буду делиться тем что делаю.
Рейтинг: 5.00. Голосов: 2.

Моделирование жидкости

Запись от Герыч размещена 03.07.2009 в 00:28
Обновил(-а) Герыч 04.08.2009 в 22:44

Как и обещал, рассказываю как делать физическую модель воды в программе.
Сразу говорю, метод который я вам поведую нужен для моделирования всей массы жидкости, а не только её поверхности.
Итак, начнём!
В этой статье поговорим о том, как смоделировать жидкость методом под названием SPH(Smoothed Particle Hydrodynamics, гидродинамика сглаженных частиц).
Где можно почитать/поглядеть поподробней? Приведу небольшой список того, что я нарыл: Русская вики, буржуйская вики, хорошая статья с примером на С++, основная pdf статья(фактически рассказан алгоритм), pdf-ка, которая не очень нужна, только для понимания, статья про реализацию этого дела, некоторые демки одного чела

Что есть SPH по сути? Идея метода в том, что у нас есть жидкость, она представляется дискретно, несколькими частицами. Частицы взаимодействуют между собой только на каком-то расстоянии. При этом умные дядьки придумывают сложные формулы и странные слова, типа "функция ядра", чтобы всё это дело описать. Функция ядра - это функция, которая зависит от расстояния между двумя частицами.
Реальная жидкость имеет такую особенность, что различные её свойства изменяются в ней непрерывно. Невозможно, чтобы давление в жидкость в одной точке и в точке, очень близкой к ней, были сильно разными. Поэтому эти умные бородатые дядьки, которые разбили воду на частицы своими формулами делают так, чтобы сохранялась эта непрерывность.
Вот их формула, на которой держится вся эта теория:
AS(r) =Σmj*Aj/ρj*W(r−rj ,h)
A - некоторое свойство частиц, m-масса частицы, ρ - плотность жидкости в частице, W(r−rj ,h) - функция ядра, которая зависит от расстояния между частицами и как-бы от расстояния h, на котором они взаимодействуют.
Объясню формулу. Пусть у каждой точки можно задать своё свойство A, тогда если мы знаем значение этого свойства у её соседей, то мы знаем значение свойства и в этой точке. W определяет степень влияния другой точки, в зависимости от удалённости.(если хотите промыть себе мозги на эту тему, читайте тут)

Ну а теперь открою тайну=) То что наверху-ненужный бред! Чтобы всё сделать не надо понимать почти ничего сверхъестественного! Всё что надо знать-элементарную школьную физику. Помните, что на тела могут действовать силы? Что они имеют скорости? Что они имеют массу и положение в пространстве, тогда всё дальше вы поймёте)

Во-первых, как я моделирую физику вообще? Использую так называемую интеграцию верлета. Идея такая:
пусть X(t) - положение частицы в момент времени t,
v(t) - её скорость
a(t) - её ускорение(т.е. сила делённая на массу, но дальше везде m=1)
X(t+dt)=X(t)+V(t)*dt+a(t)*dt^2/2 //Положение в следующий момент времени
X(t-dt)=X(t)-V(t)*dt+a(t)*dt^2/2 //Положение в прошлый момент времени
Сложим эти два равенства, получим:
X(t+dt)+X(t-dt)=2*X(t)+a(t)*dt^2
или по-другому:
X(t+dt)=X(t)+(X(t)-X(t-dt))+a(t)*dt^2
Т.е. новое положение можно определить не зная скорости. Кажется, в чём кайф этой записи? А он в том, что прошлое и новое положение можно менять на своё усмотрение(к примеру при столкновении со стеной надо менять не скорость, а положение точки, всё остальное скорректирует формула).
Теперь ясно, что для каждой частицы нам надо знать 3 величины: X, Xold, a
X и Xold - вычисляются каждый раз, когда мы применяем формулу:
Код:
tmp=x;
x=x+(x-xold)+a;
xold=tmp;
тут dt=1 для простоты.
То есть задачка сводится к поиску ускорения a для каждой частицы, и весь алгоритм сводится к такой схеме:
Код:
для всех частиц a=0
ищем a           //Описано ниже
применяем формулу выше
если x вышла за границы, то возвращаем обратно
Осталось найти ускорение a. Вот тут уже будет наш SPH. вообще достаточно подробно рассказано тут: хорошая статья с примером на С++, основная pdf статья(фактически рассказан алгоритм), но поскольку буржуйский язык нам чужд, то я всё расскажу тут.

Для каждой частицы заводим дополнительные значения ro, ro_near - плотности воды в частицы, press, press_near - давления в частице.
Также храним общие параметры(выбираются до эксперимента): h - радиус взаимодействия частиц, k - коэффициент для преобразования ro в press, k_near - для ro_near в press_near, rest_ro - та плотность, которое должно быть в частице по умолчанию(нулевая плотность, как я буду её звать).
Почему ro и ro_near? Идея в том, что частицы по-разному взаимодействую на разных расстояниях. Вблизи они сильно отталкиваются, вдалеке притягиваются, поэтому считают сразу 2 значения. rest_ro - определяет насколько сильно частицы притягивает друг к другу. Это как для пружины длина нерастянутой пружины. Т.е. частицы притягиваются, если в частице плотность ниже нулевой и отталкиваются в другом случае.

Теперь к алгоритму:
Код:
Обнуляем для каждой частицы p:
  p.ro, p.ro_near, p.press, p.press_near
Ищем все пары частиц на расстоянии d таком, что d<h
для каждой пары соседей
{
  считаем параметр q=1-d/h, q2=q*q и q3=q2*q
  для обеих точек из пары делаем:
  {
    p.ro+=q2
    p.ro_near+=q3
  }
}

Потом для каждой точки p
{
  p.press = k * (p.ro - rest_ro);
  p.press_near = k_near * p.ro_near;
}

Потом для каждой точки p:
{
  s=0
  для каждого соседа q точки p:
  {
    tmp=(p.x-q.x)*((p.press + q.press)*q + (p.press_near + q.press_near)*q2)/d        //q, q2, d для каждой пары свои
    q.a+=tmp;
    s+=tmp;
  }
  p.a-=s;
}
Обратите внимание, что a,x,xold - вектора!
В этом месте советую всё же поглядеть на исходник к этой статье, ибо он прояснит все ваши непонятки.
Всё, алгоритм описан.

Теперь 2 главных вопроса, которые я себе задаю:
1) зачем я всё это написал
2) нужно ли это кому-нибудь
А теперь ответ на ваш закономерный вопрос "ты дурак это во флэше делать?" - да

Если blog.brandonpelfrey.com не работает, то вот эта статья и сходник: ссылка
Удачи!
Размещено в Физика
Комментарии 13 Отправить другу ссылку на эту запись
Всего комментариев 13

Комментарии

Старый 22.07.2009 19:02 Venya2007 вне форума
Venya2007
Герыч,маладца. Я как раз искал алгоритми жидкости, спасибо, есть что почитать.Продолжай в том же духе.
Старый 22.07.2009 20:56 Герыч вне форума
Герыч
 
Аватар для Герыч
Будут вопросы, спрашивай
Старый 04.08.2009 19:51 TERRORist вне форума
TERRORist
 
Аватар для TERRORist
сапасибо большое, оч интересно, уверен, что пригодится!
Старый 04.08.2009 20:52 Герыч вне форума
Герыч
 
Аватар для Герыч
угу) Надо бы ещё описать то, как делать желе..
Старый 04.08.2009 22:17 TERRORist вне форума
TERRORist
 
Аватар для TERRORist
Цитата:
Потом для каждой точки p:
s=0
а S это что?

З.Ы блог Брендона Пелфри мертв кстати, так что исходников нема(
Обновил(-а) TERRORist 04.08.2009 в 22:26
Старый 04.08.2009 22:37 Герыч вне форума
Герыч
 
Аватар для Герыч
исходники у меня есть, копия странички блога тоже) экстренно из кэша гугла скопировал, пока там была) Вот, качай: http://pingvin.nnov.ru/files/get.php?ind=32
Старый 04.08.2009 22:39 TERRORist вне форума
TERRORist
 
Аватар для TERRORist
спасибо!
Старый 04.08.2009 22:45 Герыч вне форума
Герыч
 
Аватар для Герыч
да, а в алгоритме я чуток напутал.. уже исправил)
Старый 05.08.2009 14:56 TERRORist вне форума
TERRORist
 
Аватар для TERRORist
А ты не пробовал делать просчет через ShaderJob и рисовать шейдерами?
Старый 05.08.2009 19:27 Герыч вне форума
Герыч
 
Аватар для Герыч
Я не знаю что это(я вообще не знаю возможностей флэша), но сейчас прочитаю)
Старый 05.08.2009 23:07 Герыч вне форума
Герыч
 
Аватар для Герыч
Итак, убил вечер на то, чтобы понять что есть Pixel Bender и шейдеры.. и не понял как:
Цитата:
делать просчет через ShaderJob и рисовать шейдерами
Можешь пример того, как ты себе это представляешь, привести?
Старый 06.08.2009 02:09 TERRORist вне форума
TERRORist
 
Аватар для TERRORist
Предполагается, что ShaderJob может быстро переваривать большие объемы инфы, в основном благодаря тому что операции с плавающей точкой быстро выполняются.

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

насчет производительности - флешовые шейдеры вполне шустро рисуют всякое в полноэкранном режиме, попиксельно.

http://help.adobe.com/ru_RU/AS3LCR/F...ShaderJob.html
http://injun.ru/flash10api/flash/display/ShaderJob.html
http://novikovd.com/2009/07/28/eshhe...ixel-blendera/

я в принципе несколько уже шейдеров написал,
Старый 06.08.2009 02:16 TERRORist вне форума
TERRORist
 
Аватар для TERRORist
 

 


Часовой пояс GMT +4, время: 01:10.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.