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


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.