Блог пользователя shilov

Автор shilov, 11 лет назад, По-русски

Доброго времени суток!

Возникла следующая задача. Имеется пара пересекающихся невыпуклых тел на плоскости. Необходимо переместить одно из тел на минимальный вектор так, чтобы ликвидировать пересечение. Для выпуклых тел существует известный алгоритм EPA. Для решения описанной задачи рекомендуют разбивать тело на выпуклые части и уже для них применять алгоритм EPA, но мне так и не понятно как выпуклая декомпозиция может помочь. Больше ничего по этому вопросу нагуглить не удалось.

Буду благодарен за любые разъяснения или ссылки на другие подходящие алгоритмы.

  • Проголосовать: нравится
  • +8
  • Проголосовать: не нравится

»
11 лет назад, # |
Rev. 3   Проголосовать: нравится +8 Проголосовать: не нравится

Тебя интересует точное решение в общем случае или какое-то более частное или приближенное?

Обычно GJK/EPA применяется в физических движках для устранения взаимного проникновения. Т. к. при симуляции происходит интегрирование координат и скоростей за небольшие промежутки времени, проникновение как правило получается небольшим по сравнению с размерами тел. В этом случае декомпозия выручает: мы просто тестируем все возможные пары выпуклых частей на пересечение и выбираем максимальное. EPA также подскажет нам точку и вектор проникновения.

В общем случае, когда тела сложные, а проникновение очень большое (т. е. общее пересечение очень большое и затрагивает несколько выпуклых фрагментов) не очень понятно, как решить задачу.

  • »
    »
    11 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Да, в моем случае проникновение может быть достаточно большим, поэтому и возникли проблемы. При этом длина вектора перемещения не обязательно должна достигать глобального минимума (сначала хочется научиться хоть как-нибудь решать эту задачу))

»
11 лет назад, # |
  Проголосовать: нравится +11 Проголосовать: не нравится

Для выпуклых фигур можно посчитать множество тех сдвигов, при которых пересечение не пусто (на этом, по-видимому, основан этот ваш известный алгоритм). Такое же множество можно построить для невыпуклых фигур примерно так:

  1. Пусть даны фигуры A и B
  2. Разделим их на множества выпуклых: A = A_1 + A_2 + A_3 ... A_n; B = B_1 + B_2 + ... U B_k
  3. Найдём множества сдвигов для всех пар частей: C_ij = S(A_i, B_j)
  4. Объединим все эти множества: C = Sum_{i,j} C_ij

Если найти на границе этого множества точку, ближайшую к началу координат, получим ответ на задачу.