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

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

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

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