Невеликі, швидкісні зіткнення об'єктів: уникнення тунелювання


14

РЕДАКТУВАННЯ / ОНОВЛЕННЯ: Найбільше моє питання зараз - це те, чи є рівняння "t = ..." кроку 3 гарною ідеєю чи є кращий спосіб це зробити. Більшість інших питань були частково або повністю вирішені, але жодних коментарів і відповідей це питання не стосувалося. Знову ж таки, ймовірно, потрібне аналітичне рішення, швидкість і відстані занадто великі, а об'єкти - занадто малі, для будь-якого ітеративного / рекурсивного рішення (кілька запропонованих нижче в коментарях), про які я можу подумати (хоча якщо є спеціальне ітеративне / рекурсивне рішення, яке буде добре справлятися з подібними ситуаціями, тоді я безумовно відкритий для цього). Дуже дякую за вашу допомогу до цих пір, ви всі приголомшливі, і я дуже ціную ваші думки та допомогу!

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

Рейтове лиття не вийде, оскільки це виявляє зіткнення між двома швидкісними об'єктами, а не між одним об'єктом та нерухомою стіною. (Якщо тільки я не розумію рентгенівське лиття?) Виконання ДУЖЕ СУЧАСНО; якщо це взагалі можливо, я хочу уникати великого хіта на продуктивність. У мене вже є реалізований функціональний і дуже ефективний квадри ( http://en.wikipedia.org/wiki/Quadtree ), тому я повинен модифікувати та використовувати його, як описано нижче.

Редагувати: Скорочення інтервалу часу не вийде. Швидкість для цього рішення є занадто високою, а це означає, що враження від продуктивності було б занадто великим, тоді як все-таки пропала б переважна більшість зіткнень з тунелем . (Наприклад, у мене може бути об'єкт розміром приблизно 1 одиниця, що рухається зі швидкістю, яка вимірюється мільйонами одиниць за часовий інтервал ...)

ПРЕДЛОЖЕНО РІШЕННЯ:

Крок 1:

Створіть поле навколо руху кожного об'єкта, а потім подайте ці поля в квадрати, щоб створити початковий список можливих зіткнень. Дивіться наступне зображення (на цьому зображенні показано об’єкт кола, що переміщується з одного положення в інше, і рух, що генерує прямокутник, який буде поданий у квадратик):Прямокутник, породжений рухом

Крок 2: (можливо, хочете пропустити цей крок?)

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

РЕДАКТУВАННЯ: Нижче Шон Міддлідч запропонував використовувати промітні томи / перетин капсул (якщо об’єкти - кола). Це залишає три варіанти: 1) повністю пропустити крок 2. 2) Зробіть крок 2 моїм шляхом. 3) Зроби це Шоном. Шона Шона буде дорожче обчислювальною, ніж моя ідея коробки, однак він викреслить більше помилкових позитивів, ніж мій шлях, не даючи їм дійти до останнього кроку.

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

Крок 3:

Використовуйте рівняння t = нижче, якщо дискримінант (тобто частина під квадратним коренем) від'ємний або 0, немає зіткнення, якщо позитивний, тоді використовуйте значення t як момент зіткнення (після чого легко регулювати положення відповідно. .. якщо обидва об'єкти продовжують існувати після зіткнення). Рівняння:

t = (-1/2 sqrt ((2 a w-2 a x + 2 b y-2 b z-2 c w + 2 c x-2 d y + 2 dz) ^ 2-4 (w ^ 2- 2 w x + x ^ 2 + y ^ 2-2 y z + z ^ 2) (a ^ 2-2 a c + b ^ 2-2 b d + c ^ 2 + d ^ 2-r ^ 2-2 r ss ^ 2)) - a w + a xb y + b z + c wc x + d yd z) / (w ^ 2-2 w x + x ^ 2 + y ^ 2-2 y z + z ^ 2 ) .

Де (1 і 2 використовуються для позначення об'єктів 1 і 2):

t - від'ємне значення часу між 0 і -1, де 0 - поточний кадр, а -1 - попередній кадр;

a = x позиція 1;

b = y положення 1;

c = x положення 2;

d = y положення 2;

w = x швидкість 1;

x = x швидкість 2;

y = y швидкість 1;

z = y швидкість 2;

r = радіус 1;

s = радіус 2;

Виведення: (^ 2 означає квадрат)

Візьміть параметричні рівняння (наприклад, newxpos1 = a + t w) для рухів об’єктів і підключіть їх до формули відстані (склавши обидві сторони): формула відстані в квадраті = (a + t w - (c + t x)) ^ 2 + (b + t y - (d + t * z)) ^ 2. Пам'ятайте, що т буде негативним. Щоб знайти час зіткнення для двох кругових об’єктів, встановимо ліву сторону рівну (r + s) ^ 2. Розв'язуючи для t, використовуючи квадратичне рівняння (і велику кількість дуже втомливої ​​алгебри), отримуємо вищевказане рівняння "t = ...".

Мої запитання:

1) Це хороший спосіб зробити це? Чи буде це взагалі працювати? Чи збираюся я зіткнутися з будь-якими непередбаченими проблемами? (Я знаю, що у мене виникнуть проблеми, коли одночасно стикаються більше двох об'єктів, але мені все одно, оскільки єдиний випадок, на який я дійсно заперечую, - це коли вони мають низькі відносні швидкості (якщо відносні швидкості великі тоді рішення "goofy", яке дає алгоритм, буде "досить хорошим", і людині буде неможливо побачити помилку), і якщо більше 2-х зіткнуться з низькими відносними швидкостями за один і той же часовий крок, більшість рішень все одно бути досить близьким, оскільки я не збираюся мати купу нееластичних зіткнень)

2) Чи сильно постраждає моя вистава? Я не думаю, що це буде, але якщо буде, чи є кращий спосіб це зробити?

3) Чи слід пропустити крок 2 і перейти прямо від кроку 1 до 3? Очевидно, що крок 2 не є життєво важливим, але це може сприяти продуктивності (АБО це може коштувати більше процесорного часу, ніж економить).

Усі інші коментарі, пропозиції чи критики дуже вітаються. Дякую за твою допомогу!


1
Крістер Еріксон має деяку інформацію про тестування сфери / сфери у своїй помаранчевій книзі. Існує досить багато способів вирішити проблему, але я думаю, що вам найбільше сподобається інтервал. Добре спробувати витягнути цей матеріал самостійно, але вам справді варто просто переглянути помаранчеву книгу і порівняти, щоб отримати дійсно гарну процедуру виявлення та дізнатися більше.
RandyGaul

Здається, у вас вже є план .. спробуйте і подивіться, як він працює?
Тревор Пауелл

Я думаю, що "звичайним" способом є невеликий максимальний проміжок часу на дельті. Отже, якщо у вас є тривалість 1000 м, просто імітуйте 10x 100ms (або 100x 10ms, або 33x 30ms, або щось подібне).
ashes999

@RandyGaul Я переглянув алгоритм, описаний на сторінці 215-218, особливо на сторінці 218 (попередній перегляд Google). Це досить елегантно, хоча я ще не продумав усіх його наслідків, сильних та слабких сторін. Чи буде це набагато швидше, ніж у мене? Якщо так, то яка частина мого алгоритму повільна порівняно з рекурсією Еріксона? Чи буде рівняння на кроці 3 занадто повільним? Рекурсія змушує мене вагатися, оскільки деякі об'єкти можуть ДУЖЕ швидко рухатися, і тому в деяких випадках може знадобитися велика кількість рекурсій. (Також OUCH, 70 доларів за цю книгу ...)
MindSeeker

1
@MindSeeker У мене немає часу, щоб розглянути ваші виводи, але я впевнений, що алгоритми в книзі Еріксона, будь-який з них, будуть працювати дуже добре і, ймовірно, будуть швидшими та надійнішими за ваші речі. Ви можете знайти версії PDF в Інтернеті безкоштовно, якщо ви хочете демонструвати інші сторінки. Крім того, якщо ви збираєтеся часто виявляти зіткнення, помаранчева книга є основним.
RandyGaul

Відповіді:


9

Ви, по суті, створили дещо надто захоплену версію розгорнутих томів .

Займіть дві позиції об’єкта. «Підмітайте» об’єкт від його початку до кінця. Для сфери це створило б капсулу. Для коробки це створило б шестикутник (або довший ящик - це рух по одній осі). Для загальних опуклих багатокутників це створило б інший опуклий багатокутник.

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

Інший варіант, дещо простіший, - це зробити те, що заявив @ ashes999, і просто використовувати менший часовий інтервал або менші швидкості. Існує ідеальна максимальна швидкість, отримана з інтервалу, в якому жоден об'єкт не може рухатися далі, ніж його вузька сторона, за один фізичний інтерес. Для особливо маленьких або особливо швидких об'єктів ви не зможете знайти достатньо малий інтервал, який добре працює.

Дивіться Виявлення зіткнення в реальному часі для однієї з кращих вступних / посередницьких книг на тему виявлення зіткнень.


Дякуємо за чудовий внесок! Збиваючи свою відповідь, щоб я міг задати питання щодо неї: "" Підмітайте "об'єкт від його початку до кінця". Поки я стежу; безумовно, покращення в порівнянні з моїм методом коробки. Я подаю ці фігури квадратом, а потім перевіряю на точніші зіткнення. "Ви можете порахувати, коли сталося зіткнення." Ха-ха, простіше сказати, ніж зробити :) Ти рекомендуєш мені дотримуватися свого рівняння з кроку 3 за крок? Або є кращий спосіб? Це справді критична частина.
MindSeeker

[продовження] "Інший варіант ..." Я подумав над цим варіантом, але, на жаль, швидкість занадто висока. Дивіться мою відповідь на коментар до @ ashes999 та редагуйте вище для отримання додаткової інформації. Велике спасибі за вашу допомогу!
MindSeeker

Єдиний спосіб дізнатися про продуктивність - це спробувати її, виміряти і побачити. Раніше я бачив, що деякі "очевидно" неефективні коди масово перевищують ефективні версії, як правило, з досить неінтуїтивних причин. Не питайте, що найшвидше; перевірити і дізнатися.
Шон Міддліч

Досить справедливо, я продовжую спробувати свій метод, модифікований так, як ви запропонували. Моє запитання в коментарі все ще стоїть: "Ви можете розрахувати, коли сталося зіткнення". Ви рекомендуєте мені дотримуватися свого рівняння з кроку 3 для цього кроку? Або є кращий спосіб? Це найскладніша частина проблеми, яку я думаю. Промітання томів, якщо я правильно їх розумію, може сказати мені, що шляхи об’єктів перетинаються, але не можу сказати, чи / коли самі об'єкти стикаються.
MindSeeker

1
@MindSeeker Swept геометрія - це радіація, за винятком того, що ви викидаєте фігуру замість променя. Таким чином, метод повинен виглядати аналогічно використанню лиття променів з "променями" для всіх об'єктів, що швидко рухаються, а не лише одного променя проти нерухомого об'єкта. Визначивши потенційні зіткнення з "променями", вам потрібно вирішити час на обох "променях", щоб переконатися, що вони опинилися на одному місці одночасно.
каменеметал

2

Алгоритм, запропонований у запитанні, працює чудово: він швидкий і абсолютно точний , навіть коли об’єкти йдуть з надзвичайною швидкістю. У мене реалізовано квадратне дерево, тому після подачі коробки від кроку 1 до квадрату я виявив, що крок 2 є непотрібним: моя програма працює майже так само швидко, як і раніше.

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


1

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

Ось посилання на дивовижну відповідь Сем Хочевар, яка дає найкращі пояснення щодо цього, які я коли-небудь знайшов (він також малював фотографії, ура!)

/gamedev//a/55991/112940

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

Тільки, щоб не залишати "відповідь лише на посилання", я надам короткий підсумок його ідеї:

  1. обчислити різницю Міньковського між двома обмежувальними полями
  2. використовуючи відносну швидкість між тоді, киньте відрізок променя / лінії від початку до поля, створеного різницею Міньковського, щоб отримати точку перетину
  3. Якщо промінь потрапить, розділіть відстань, яку промінь промінь, на довжину вектора, що представляє відносну швидкість, і ви отримаєте своє "t"
  4. натисніть на посилання, яке я надав вище, і подивіться дуже красиве пояснення всього цього, з великою кількістю фотографій. Це приголомшливо.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.