Алгоритм расстояния Гилберта–Джонсона–Кирти — это метод определения минимального расстояния между двумя выпуклыми множествами , впервые опубликованный Элмером Г. Гилбертом , Дэниелом У. Джонсоном и С. Сатией Кирти в 1988 году. В отличие от многих других алгоритмов расстояния, он не требует, чтобы геометрические данные хранились в каком-либо определенном формате, а вместо этого полагается исключительно на вспомогательную функцию для итеративной генерации более близких симплексов к правильному ответу с использованием препятствия в конфигурационном пространстве (CSO) двух выпуклых фигур, более известного как разность Минковского .
Алгоритмы "Enhanced GJK" используют информацию о ребрах для ускорения алгоритма путем отслеживания ребер при поиске следующего симплекса. Это существенно повышает производительность для многогранников с большим количеством вершин.
GJK использует подалгоритм расстояния Джонсона, который в общем случае вычисляет точку тетраэдра, ближайшую к началу координат, но, как известно, страдает от проблем с числовой надежностью. В 2017 году Монтанари, Петринич и Барбьери предложили новый подалгоритм, основанный на знаковых объемах, который избегает умножения потенциально малых величин и достиг ускорения от 15% до 30%.
Алгоритмы GJK часто используются пошагово в системах моделирования и видеоиграх. В этом режиме окончательный симплекс из предыдущего решения используется как начальное предположение в следующей итерации или «кадре». Если позиции в новом кадре близки к позициям в старом кадре, алгоритм сойдется за одну или две итерации. Это дает системы обнаружения столкновений, которые работают почти за постоянное время.
Стабильность, скорость и небольшой объем памяти алгоритма делают его популярным для обнаружения столкновений в реальном времени , особенно в физических движках видеоигр .
GJK опирается на две функции:
Симплексы, обрабатываемые NearestSimplex , могут быть любым симплексным подпространством R n . Например, в 3D они могут быть точкой, отрезком прямой, треугольником или тетраэдром ; каждый из них определяется 1, 2, 3 или 4 точками соответственно.
функция GJK_intersection(форма p, форма q, начальная_ось вектора): вектор A = Support(p, initial_axis) − Support(q, −initial_axis) симплекс s = {A} вектор D = −A петля : A = Поддержка(p, D) − Поддержка(q, −D) если точка(A, D) < 0: отклонять с = с ∪ {А} s, D, содержит_источник := NearestSimplex(s) если содержит_источник: принимать