Дозвіл зіткнення у разі зіткнення з декількома об'єктами


15

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

Наприклад, у цій ситуації у мене є два статичні об'єкти (червоним кольором):

введіть тут опис зображення

і рухомий предмет між двома:

введіть тут опис зображення

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

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

введіть тут опис зображення

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

Загальним способом підходу до цього було б вирішити лише зіткнення одного зіткнення на кадр, а не всі відразу. Але в моєму випадку це призведе до перевертання:

По-перше, розв'язувач виявляє два зіткнення, але вирішує лише зіткнення між правим прямокутником і зеленим прямокутником:

введіть тут опис зображення

Потім у наступному кадрі він виявляє лише одне зіткнення, яке знаходиться між лівим червоним прямокутником та зеленим прямокутником, і вирішує його:

введіть тут опис зображення

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

Як я можу це вирішити?


У своєму прикладі ви використовуєте прямокутники. Чи вирішує ваш алгоритм зіткнення лише зіткнення лише на одній осі? Якщо так, то має сенс, що поведінка, яку ви описуєте, відбувається.
chaosTechnician

Ні, він може вирішити їх будь-якими формами на всіх можливих осях (не тільки прямокутники, їх просто найпростіше намалювати фарбою MS: P), і він завжди знайде найкоротший вектор, який існує, який штовхне два об'єкти .
TravisG

+1 Добре запитання. Я видалив (2D) "тег" із заголовка, це те, чого вам слід уникати (див. Мета ).
bummzack

Відповіді:


7

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

Ось деталі: http://www.wildbunny.co.uk/blog/2011/03/25/speculative-contacts-an-continuous-collision-engine-approach-part-1/

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

Якщо вам потрібно / хочете більше, ви можете придбати його вихідний код за (IIRC) 7 доларів.

Ось відео про мою реалізацію в 3D: http://www.youtube.com/watch?v=JvT2H1RmOas

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


2

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

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


Додайте до зіткнень невеликий випадковий вектор з величиною приблизно epsilon * 10? Арифметика з плаваючою комою повинна робити все інше.
Мартін Сойка

2
Так, це, можливо, спрацює. Але це також може створювати тремтіння рухів.
Mihai Maruseac

1
Я сподіваюся, що все-таки зможу отримати відповідь на це: обчислення результату виправляє проблему "нескінченного циклу", але знову вводить проблему "тріщини", коли переміщення під час ковзання по стіні з плитки однакового розміру змушує тіло отримати застряг між «тріщинами» плитки. Чи є спосіб вирішити обидві ці проблеми?
Вітторіо Ромео

Погодьтеся, немає найкращої "правильної відповіді" для вирішення такого неможливого зіткнення з твердим тілом. Або воно тремтить, або ви допускаєте певну «каламутність» в одному або декількох об’єктах.
Девід ван Брін

0

Якщо ви уважно придивитесь до цього, такий стан об’єктів є (або повинен бути) недосяжним.

Нехай крайній лівий червоний має форму R1, а правий крайній червоний має форму R2. Нехай зелена форма буде G.

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

 (1) G could not have been just directly to the left of R2, since R1 has been there 
     already. Consequently, the translation of G from left to right, penetrating R2
     could not have occurred.
 (2) G could not have been just directly to the right of R1 since R2 has been there 
     already. Consquence of which is the same as that from (1).
 (3) Had G come from the top, the movement will be blocked by both R1 and R2, given
     that their geometry and Y coordinate is the same.

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

Якщо G перевіряється на R1 після того, як він перевіряється на R2, то G здається, що юридично знаходиться праворуч від R1 (якщо G скаже, що наближається до R1 у напрямку вектора <-1, -1> з довільною величиною (або відстані) ), тому що перевірка між R1 і G дозволяє це, і забуває про перевірку між R2 і G, яка робилася раніше.

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

Зауважте, що в заданому кадрі об'єкт (наприклад, G) може мати лише ОДИН напрямок. (о людино, це схоже на хлопця ...)

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