Я пытаюсь внедрить систему столкновений в 2D-игру, которую я делаю. Теорема о разделяющей оси (как описано в учебнике по столкновению с metanet ) кажется эффективным и надежным способом обработки обнаружения столкновений, но мне не совсем нравится метод реагирования на столкновения, который они используют. При слепом смещении вдоль оси наименьшего перекрытия алгоритм просто игнорирует предыдущую позицию движущегося объекта, что означает, что он не сталкивается со стационарным объектом так сильно, как входит в него и затем отскакивает.
Вот пример ситуации, когда это будет иметь значение:

Согласно методу SAT, описанному выше, прямоугольник просто выпадет из треугольника, перпендикулярного его гипотенузе:

Однако реально, прямоугольник должен остановиться в нижнем правом углу треугольника, так как это будет точка первого столкновения, если он будет непрерывно двигаться вдоль своего вектора смещения:

Теперь, это может на самом деле не иметь значения во время игры, но я хотел бы знать, есть ли способ эффективно и вообще добиться точных перемещений таким образом. Последние несколько дней я ломал голову над этим, и пока не хочу сдаваться!
(Перекрестная публикация от StackOverflow, надеюсь, это не противоречит правилам!)
Шаг 1: Для каждого многоугольника найдите две самые дальние точки вдоль проекции этого многоугольника на линию, перпендикулярную вектору движения.
Шаг 2: Разделите каждый многоугольник вдоль линии, соединяющей эти точки. Половина многоугольника, которая обращена к другому многоугольнику вдоль вектора движения, является "передней оболочкой". Это единственная часть многоугольника, которая может столкнуться.
Шаг 3:Спроецируйте вектор из каждой точки "передней оболочки" каждого многоугольника вдоль вектора движения в направлении противоположного многоугольника и проверьте его на предмет пересечения с каждым ребром "передней оболочки" противоположного многоугольника. (Возможно, медленный, но в наше время компьютеры работают довольно быстро - верно?) (Извините за наклонную стрелку. Все стрелки должны быть параллельны.)
Шаг 4: Возьмите кратчайший вектор. Это точное расстояние столкновения.
Шаг 5: Вуаля!
