2D реакція на зіткнення гри: SAT & мінімальний переміщення вздовж заданої осі?


13

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

Ось приклад ситуації, коли це має значення:

Приклад

Відповідно до описаного вище методу SAT, прямокутник просто вискочить з трикутника перпендикулярно його гіпотенузі:

Відповідь у стилі SAT

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

Реалістична відповідь

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

(Перехресне повідомлення від StackOverflow, сподіваюся, що це не суперечить правилам!)


Це проти правил. Не перехрещуйтесь.
AttackingHobo

Так, видаліть його з StackOverflow і збережіть його тут: P
TravisG

gamedev.stackexchange.com/questions/9144/… Я відповів на ваше конкретне запитання тут.
ultifinitus

Видалено з SO.
Архагон

Початок щедрості, архагон: P Інакше, можливо, доведеться. Це питання дійсно цікаве, і було б дивовижно побачити відповідь, яка більше, ніж просто перерахувати пару посилань.
TravisG

Відповіді:


11

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

На малюнках, представлених нижче, синій предмет рухається, а червоний - нерухомий. 1 Крок 1. Для кожного багатокутника знайдіть дві найдальші точки уздовж проекції цього многокутника на лінію, перпендикулярну вектору руху. 2 Крок 2: Розділіть кожен многокутник по лінії, що з'єднує ці точки. Половина багатокутника, яка стикається з іншим багатокутником уздовж вектора руху, - це "корпус вперед". Це єдина частина полігону, яка може зіткнутися. 3 Крок 3:Спроектуйте вектор з кожної точки на "корпус" переднього корпусу кожного полігона вздовж вектора руху до протилежного багатокутника і перевірте його на перетин з кожним краєм "переднього корпусу" протилежного полігона. (Можливо, повільно, але комп’ютери зараз досить швидкі - так?) (Вибачте за нахилену стрілку. Усі стрілки повинні бути паралельними.) 4 Крок 4: Візьміть найкоротший вектор. Це точна відстань зіткнення. 5 Крок 5: Вуаля! 6


2
Це досить вражаюче. Ви випадково порівняли швидкість роботи свого алгоритму з простим (4х або 8-кратним) мультисемплінг?
TravisG

На жаль, немає.
Архагон

Вражає, і я впевнений, що математика теж не дуже складна / інтенсивна. +1
you786

7

Ознайомтесь із подібним запитанням: Дозвіл щодо зіткнення

А також з http://www.metanetsoftware.com/technique/tutorialA.html#section5 (на який ви розмістили посилання на :))

РОЗДІЛ 5: Об'єкти, що швидко рухаються

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

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

- = тести промітання = -

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

Основна ідея описана в [Гомес] для тестів кругообігу та AABB-AABB тестів.

- = мультисемплінг = -

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

Якщо ви переконаєтесь, що зразки завжди розташовані на відстані менше радіуса об'єкта, це дасть чудові результати. У нашій реалізації ми обмежуємо максимальну кількість зразків, тому дуже великі швидкості іноді можуть спричинити проблеми; це те, що можна налаштувати на основі вашої конкретної програми.

EDIT

Підсумовуючи та AFAIK, є кілька рішень

  1. Обмежте свою гру, щоб ніколи не було маленького та / або швидко рухається предмета, який навіть може спричинити це
  2. Вкажіть систему, яка зупиняє зіткнення насправді, як це описано у першому посиланні, яке я розмістив
  3. Збільшити показник вибірки для швидких та / або малих рухомих об'єктів
  4. ... можливо більше, але я не експерт.

1

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

Альтернатива використанню SAT:

У випадку лінійного лише ви можете відкинути промінь проти різниці Міньковського двох многокутників від початку в напрямку дельта-лінійної швидкості об’єктів.

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

Тепер, якщо об’єкти рухаються і обертаються, стає складніше, але ви все одно можете використовувати подібну техніку. Консервативне просування дозволить вам розібратися з цією справою. Ця методика є ітеративною; кожна ітерація породжує новий МД та наблизить вас до часу перетину.

Ось оригінальний проект документа про консервативне просування:

http://www.continuousphysics.com/BulletContinuousCollisionDetection.pdf

Я написав статтю, де детально пояснював цю техніку:

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

Сподіваюся, ці допоможуть!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.