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

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

Рейтинг: 5.00. Голосов: 2.

Эксперименты с физикой. Часть 5.

Запись от Волгоградец размещена 12.05.2010 в 10:06

Сегодня поговорим о коллизиях. Рассмотрим столкновение шара и бесконечной плоскости. Затем добавим столкновение между шарами. Для определения коллизии шар-плоскость можно использовать знаменитую теорему о разделяющих плоскостях. Звучит она так - если между телами есть такая плоскость, которая эти тела разделяет - значит тела не пересекаются (логично). На словах звучит не очень понятно - попробуем визуализировать. Представим, что на столе лежит яблоко. Возьмем теперь лист бумаги и попытаемся просунуть его между столом и яблоком. Естественно это сделать не получится. Теперь поднимем яблоко и увидим, что наш лист легко проходит между телами - это и есть наша разделяющая плоскость. Но, как легко заметить, мы можем задать положение листа бесконечным количеством способов - чуть выше, чуть ниже, повернув, наклонив и т.д. Какую же именно плоскость выбрать? А использовать стоит плоскость, параллельную стороне одной из фигур. Алгоритм такой - мы берем два тела и последовательно перебираем все грани первой фигуры, проверяя - разделяет ли данная плоскость тела. Если находится хотя бы одна такая плоскость - значит тела не пересекаются. Если такой плоскости нет - переходим ко второму телу и проверяем заново.
Для нашего случая все намного проще - у нас бесконечная плоскость и шар - нужно проверить только одну плоскость - параллельную самой плоскости. Как же это сделать? Очень просто - мы берем любую точку на плоскости находим вектор из этой точки до центра шара и проецируем этот вектор на нормаль плоскости. Взглянем на рисунок.
Название: 1.png
Просмотров: 2039

Размер: 6.6 Кб

На первой картинке мы видим проекцию a вектора v на нормаль n. Легко заметить - что проекция больше радиуса шара - т.е. расстояние от плоскости до центра шара больше его радиуса - значит они не пересекаются. На второй картинке проекция a меньше радиуса, что значит, что шар пересек плоскость... Надеюсь вы помните как находить проекцию - это dot product (скалярное произведение векторов).
Переходим к делу. Заведем вспомогательный класс Wall, представляющий плоскость - она будет хранить позицию, направление и нормаль. Позиция нужна для отрисовки и нахождения вектора от точки на плоскости до центра шара (на рисунках - это точка откуда выходит вектор v). Для нахождения пересечения создадим класс ParticlePlaneCollisionDetector с единственным методом findIntersection(). Весь код для определения пересечения состоит из 4 строчек! Ни единого деления и корня! Смотрим что получилось.
ballPlaneCollision.swf

Итак, мы имеем взаимное проникновение двух тел - как теперь сделать так, чтобы визуально тела не пересекались? Элементарно - выталкиваем тело на величину проникновения вдоль нормали. И вот что вышло.
ballPlaneResolution.swf

Теперь добавим интергратор и еще пару плоскостей.
ParticlesPlanes.swf

Название: 2.png
Просмотров: 2080

Размер: 7.9 Кб
Не хватает отскоков от поверхности. На картинке показано, как найти скорость v' после отскока. Здесь e - коэффициент упругости, который принимает значения от 0 до 1 (0 - значит тело не отскочит, 1 - нормальная скорость после отскока будет такой же, как и до), f - коэффициент трения, который принимает значения от 0 до 1 (0 - значит трения нет, 1 - тангенциальная скорость после отскока будет равна 0).
ParticlesPlanesWithBound.swf

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

В демку я добавил сетку для так называемой broad phase - это фаза для определения возможности пересечения шаров. Например, если шары находятся в разных частях экрана - какой смысл их проверять. Сетка действует очень просто - размер ячейки равен диаметру шара. В каждом шаге рассчитывается какая частица находится в какой ячейке и проверяются всего 9 ячеек на предмет нахождения частиц в них. Но все равно система очень медленная - уже при 80 шарах начинаются тормоза (в релиз компиляции немного побольше) - так что есть еще место для оптимизации.
Напоследок скажу, что в системе, которую мы сделали не рассчитываются скорости после удара - поэтому после столкновения шаров они не отскакивают так как надо - но тем не менее благодаря интегратору небольшая видимость отскока есть.
Ну и напоследок несколько демок.
С помощью связей можно сделать псевдо твердое тело - например ящик.
Box.swf

Блоб - здесь он не идеален, его легко сломать.
Blob.swf

Вроде все. Я рассказал все что знаю о soft body physics. Следующие уроки (если будут) будут посвящены твердым телам - rigid bodies - будем создавать что-то типа Box2D.

tutorial5.zip
Всего комментариев 15

Комментарии

Старый 12.05.2010 23:16 incvizitor вне форума
incvizitor
 
Аватар для incvizitor
Спасибо за уроки!
Старый 13.05.2010 10:38 Tr1te вне форума
Tr1te
 
Аватар для Tr1te
Спасибо за вашу рубрику. Надеюсь будет продолжение.
Старый 04.06.2010 10:48 VARion вне форума
VARion
Спасибо! Очень интересная тема.
Попробовал добавить 180 шаров в ParticleParticlePlane.swf тормозов сильных не было, а вот "эффект попкорна" интересный получился. Шары уже не останавливаются и бурлят, периодически выплёвывая некоторые шары. Я с аналогичной проблемой сталкивался при использовании 3D движка физики (не для Flash).
Старый 04.06.2010 14:02 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
Да, это из-за того, что слишком большой шаг между интервалами, т.к. я привязываюсь к флэшовому enterFrame. Но это легко лечится добавлением итераций в цикл (но и тормозов соответственно прибавится).
Старый 05.06.2010 14:53 mikleb вне форума
mikleb
Если не лень, попробуйте пожалуйста сделать 100 боксов. Интересно намного ли тормазнее (или может быстрее) верлетовская физика чем constrain based Бокса 2д.
PS
А для 1 бокса выглядит не плохо.
Старый 05.06.2010 19:31 Ariel вне форума
Ariel
 
Аватар для Ariel
Нет rotation-a... Где rotation??
Старый 07.06.2010 12:15 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
mikleb, да, можно будет попробовать. Времени жаль очень мало.
Ariel, в том то и полезность метода Верле - создается иллюзия правдивого движения без тяжелых расчетов.
Старый 08.06.2010 23:33 Ariel вне форума
Ariel
 
Аватар для Ariel
Э-э-э.. Тяж0лые расчеты... Вот ведь шарик кружится без тяжелых расчетов.

И как это у Вас у стены (Wall) имеется _direction? Ну _position я еще могу понять, но направление, выраженное через вектор... у стены..
Зачем?
Старый 10.06.2010 23:10 Функционер вне форума
Функционер
 
Аватар для Функционер
Привет.
Отличные уроки.
У меня к вам вопрос по 5-ым туторам:
1172: Definition ru.inils.utils: Debugger could not be found.
import ru.inils.utils.Debugger - откуда взять?
Спасибо.
Старый 15.06.2010 11:41 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
Ariel, мне нужно знать наклон плоскости и точку, лежащую на этой плоскости. Для этого и нужны 2 вектора. Про rotation сначала не понял - я не реализовывал, т.к. в моей системе частиц оно не нужно. И вращение шарика по ссылке ничего общего с физикой не имеет.
Функционер, закомментируй эти строки - это для дебага.
Старый 17.06.2010 09:22 Ariel вне форума
Ariel
 
Аватар для Ariel
Да-да, ужо разобрались.. У Пеннера в книжке так и указывается. Типа, вектора юзаются, как Number2D...
И неужели в Вашем мега-двиге не будет rotation-a? Как же без него?

И еще одно. У Вас повсеместно использованы геттеросеттеры. Для таких критических участков (скорость) это не есть хорошо. Я бы даже сказал, плохо. Паблик переменные рулят!

И в детекторе столкновений у Вас сидит try-catch, шо тоже конкретно заваливает все показатели по скоростям.
Обновил(-а) Ariel 18.06.2010 в 00:38
Старый 18.06.2010 11:10 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
В первом уроке я говорил, что это туториалы с ориентированием на ООП а не на скорость - для лучшего понимания. Геттеросеттеров в моем "релизном" движке нет.
Rotation у меня есть в rigid body движке. Туториалов по нему пока не писал.
Старый 19.06.2010 03:54 Ariel вне форума
Ariel
 
Аватар для Ariel
Да, очень интересно. Скажем, как подшивать к интегратору Верле этот пресловутый rotation...
Ждем-с!
Старый 11.01.2011 09:16 Hauts вне форума
Hauts
 
Аватар для Hauts
Волгоградец, продолжение будет? Очень уж интересная тема
Старый 11.01.2011 11:26 Волгоградец вне форума
Волгоградец
 
Аватар для Волгоградец
Да, будет когда-нибудь. Наработки есть - надо привести все это в подобающий вид - но лень и нехватка времени... :-).
 

 


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


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