Дозвіл зіткнення


23

Я досить добре знаю, як перевірити на зіткнення, але я не знаю, як правильно впоратися зіткненням.

Спрощено, якщо два об'єкти стикаються, я використовую деякі обчислення для зміни напрямку швидкості. Якщо я не переміщу два об'єкти, вони все одно перекриються, і якщо швидкість не буде достатньо великою, вони все ще зіткнуться після наступного оновлення. Це може спричинити застрягнення предметів один в одному.

Але що робити, якщо я спробую перемістити два об’єкти, щоб вони не перетиналися. Це звучить як гарна ідея, але я зрозумів, що якщо об'єктів більше двох, це стає дуже складним. Що робити, якщо я переміщую два об'єкти, і один з них стикається з іншими об'єктами, тому я повинен також переміщувати їх, і вони можуть стикатися зі стінами тощо.

У мене на увазі 2D гра зверху вниз, але я не думаю, що це має багато спільного з цим. Як зазвичай справляються зіткнення?

Це питання задають від імені Wooh


1
Чи можете ви уточнити тип гри? "Зверху вниз 2D" може означати багато речей: екшн-пригодницька гра в стилі Zelda, шутер з вертикальною прокруткою або кишенькова гра в більярд. Усі вони мали б дуже різні стандартні стилі керування зіткненнями!
Ян Шрайбер

2
Я не можу цього уточнити. Питання не в тому, що станеться в результаті зіткнення, а в тому, щоб вирішити багаторазову проблему перекриття. Я думаю, що достатньо знати, що я відбиваюсь від предметів один від одного, і я хочу, щоб вони поводилися реалістично, щоб відповісти на це питання.
CiscoIPPhone

Відповіді:


16

Даніель Кодічек дуже детально висвітлює цю тему у своїй книзі « Математика та фізика для програмістів» .

Kodicek робить дві речі для досягнення природного вигляду зіткнення:

  • Його функція виявлення зіткнень обчислює точний час стикання двох об'єктів.
  • Він перераховує нові швидкості в момент зіткнення, тому об’єкти ніколи не перетинаються.

Я завантажив демонстрацію на основі виявлення та вирішення зіткнень Kodicek .

update: Ось алгоритм виявлення та вирішення зіткнень, який дуже схожий на метод Kodicek. З вихідним кодом . Я все ж рекомендую книгу Кодічека, оскільки його алгоритм реалізований дещо інакше і набагато більш ретельно пояснений.


1
Здається, ваше демо-посилання порушено.
ashes999

@ ashes999: посилання виправлено зараз!
Лефтій

Це алгоритм для кіл. Як щодо коробки?
Антон Чикін

@AntonChikin: Алгоритм вирішення зіткнення Кодічека займає лише три входи: масу, швидкість і нормальну в точці зіткнення. Kodicek завжди обчислює нормальність у точці зіткнення при виявленні зіткнень. Він пояснює багато різних типів виявлення зіткнень, включаючи коробку, що потрапляє в іншу коробку. Просто підключіть цей алгоритм виявлення зіткнення до алгоритму вирішення зіткнення. Повне пояснення див. У розділах 8-10 книги Кодичека. (Зверніть увагу, що обертальна фізика вимагає більше математики, про що також йдеться в книзі ...)
Лефтій,

1
@ThomasHilbert: демо-код та виконавчі файли Windows тепер доступні на веб-
Leftium

6

Що робити, якщо ви перевіряєте зіткнення перед тим, як об’єкти рухаються, а не після цього? Або, іншими словами, ви відхиляєте нове положення, якщо об’єкти стикаються, повторно використовуючи старе в цьому випадку?

Псевдокод:

  tmpPosition1 = Obj1.position
  tmpPosition2 = Obj2.position
  updatePosition(Obj1)
  updatePosition(Obj2)
  if collided(Obj1,Obj2) then
      updateVelocities( Obj1, Obj2 )
      Obj1.position = tmpPosition1
      Obj2.position = tmpPosition2
  endif

Таким чином об'єкти будуть натикатися один на одного, коли вони збираються зіткнутися , якщо ваш крок оновлення досить малий, гравець не повинен помічати нічого дивного в поданні.


1
Це дуже дратує, тому що ви не можете легко переміщатися паралельно об'єктам, тому що не можете рухатись на al, якщо торкаєтесь інших об'єктів.
Іке

Якщо ви вирішите x та y окремо
instantaphex

6

Кожного разу, коли два об’єкти перетинаються, перевірте, чи рухаються вони назустріч один одному. Зробіть зіткнення лише в тому випадку, якщо вони рухаються назустріч один одному.

З векторною математикою це досить просто, просто порахуйте:

dot_product (B.позиція - A.позиція, A.velocity - B.velocity)

Якщо результат позитивний, об'єкти рухаються назустріч один одному.


4

Я можу нерозуміти, але, схоже, ви задаєте два питання: 1. Які загальні способи вирішення проблеми зіткнення термін, який ви шукаєте, - це «імітація, заснована на імпульсі», і є маса документів, які можна зробити це краще, ніж я.

Підводячи підсумок, ви хочете, щоб еулер крокував своє фізичне моделювання в просторі імпульсу, що є масовою швидкістю (не робіть справи на основі сили, ваш інтегратор все одно не робить це правильно).

Для кутового реагування, на щастя, найбільший і найменший інерційний момент завжди можна звести до двох ортогональних осей (у 2D), що означає, що матричне множення буде працювати загалом, і якщо ви вирівнюєте їх з осями X і Y, це перетворюється на 2D-вектор.

При зіткненні ви розраховуєте реакцію, засновану на лінійних і кутових моментах у точці зіткнення, і хорошим фактором розтушовування є, якщо у вас взаємопроникнення, застосувати деяку штрафну силу (як зазначено вище), щоб роз'єднати ці два тіла.

З цього моменту ви додасте все більше і більше правил для контролю за відхиленою поведінкою, як, наприклад, обмеження максимального кутового імпульсу, щоб все не крутилося як вершини тощо, але це хороший початок.

Зробіть це просто, якщо зможете.

  1. Як ви вирішуєте проблеми зі стиканням декількох тіл

Єдиний реальний спосіб це зробити за допомогою системи лінійних рівнянь і багато розв’язування. Практичний спосіб зробити це - мати таку систему, як описана вище, і фізика з часом природно вирішиться.

Більшість ігор, які роблять такі речі, як кочення або стоячи на рухомих поверхнях, мають гібридну модель, коли ваші ноги прикріплені до поверхні (або колеса до дороги), щоб пристосувати час кроку фізики (це призвело б до циклів взаємопроникнення і реакції. не буде працювати).

Сподіваюся, це допомагає. Якщо вам потрібні математичні приклади, дайте мені знати.


3

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

A penalty forceзастосовується як пружинна демпфера, де штрафна сила збільшується тим більше, коли ви проникли в жорстке тіло і зменшуються в наступних кадрах. Думайте про це як про пружинах. Коли два жорстких тіла перетинаються, кожне з них стикається з невидимою пружиною, яка гасить їх прогресування (тобто перешкоджає більшому взаємопроникненню) і застосовує згадане раніше, penalty forceпоки тіла більше не проникнуть.

Це широка тема, але, сподіваємось, вищевказана інформація спонукає вас до роботи.


Тож замість запобігання взаємопроникнення цей метод дозволяє це, але надає опір, майже як об'єкти стискаються?
CiscoIPPhone

Це забезпечує опір, так, опір збільшується тим більше, як тіло намагається проникнути. На практиці, якщо у вас достатньо низький час дельта (наприклад, 10 мс), він не спричинить жодних взаємопроникнень. Однак справжня перевага цього методу полягає в тому, що у вас є тіла, які з різних причин проникли між собою (положення було змінено, вони з'єднані жорсткими тілами і їх положення були виправлені) і тепер їх потрібно відокремити, тому що без цієї методики тіла вибухне, а не поступово відокремиться.
Самаурса
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.