Расстояние между двумя выпуклыми многоугольниками в 3D - PullRequest
7 голосов
/ 25 февраля 2011

У меня есть два выпуклых многоугольника в 3D. Они оба плоские на разных плоскостях, так что это пара граней.

Какой самый простой способ вычислить ближайшее расстояние между этими двумя полигонами?

Редактировать: Длина самой короткой линии, которая имеет конечную точку в первом многоугольнике и другую другую конечную точку во втором многоугольнике. Расстояние, которое я ищу, это длина этой кратчайшей линии.

Ответы [ 5 ]

3 голосов
/ 25 февраля 2011

Это простая ограниченная оптимизация с линейными ограничениями и квадратичной целевой функцией. Есть много алгоритмов, которые можно использовать, например, градиентный спуск.

3 голосов
/ 25 февраля 2011

Ну, есть только несколько возможностей;Самая короткая линия между двумя многоугольниками может быть:

  1. Между двумя вершинами
  2. Между ребром и вершиной
  3. Между двумя ребрами (представьте два многоугольника)в перпендикулярных плоскостях)
  4. Между вершиной и внутренней частью многоугольника
  5. Или пересекаются многоугольники

Все случаи 1-3 решаютсяобработав каждую ребро + пару вершин как отрезок и перечислив расстояние между всеми парами отрезков .

Для случая 4 найдите расстояние между каждой вершиной иплоскость другого многоугольника .Убедитесь, что линия (от вершины до ближайшей точки на плоскости) находится внутри другого многоугольника;если это не так, то самая короткая линия к другому многоугольнику будет по его периметру, о котором уже позаботились в случае 1 или 2.
(убедитесь, что сделали эту проверку для обоих polygons)

В случае 5 хотя бы один отрезок должен пересекаться с площадью другого многоугольника - если бы они пересеклись по периметру, мы бы поймали его уже в случаях 1-3,и если бы вершина пересекла область, мы бы поймали ее в случае 4. Так что просто проверьте пересечение каждого ребра с плоскостью другого многоугольника и посмотрите, находится ли точка пересечения внутри другого многоугольника.
(обязательно выполните эту проверку для обоих полигонов)

Возьмите минимальное расстояние, найденное во всем этом, и все готово.

2 голосов
/ 25 февраля 2011

То, что большинство людей предложили в этой теме, это «взять все точки / ребра одного многоугольника и сравнить с каждой точкой / ребрами другого». Это, вероятно, будет работать нормально, если все, что вы делаете, это сравниваете два довольно простых полигона и если вы не слишком заинтересованы в том, чтобы делать это быстро.

Однако, если вы хотите довольно простой и лучший метод. Используйте, как предложил Бен Фойгт, метод квадратичной оптимизации (т. Е. Квадратичное программирование ). По сути, ваши полигоны - это ваш набор линейных ограничений, т. Е. Точка решения должна лежать к внутренней стороне каждого ребра полигона (это ограничение неравенства). А ваша функция затрат для оптимизации - это просто евклидово расстояние, то есть Q в стандартной формулировке - это просто матрица тождеств. Однажды приведя в качестве такой проблемы, вы можете либо использовать библиотеку, которая решает эту проблему (их много), либо вы можете изучить ее из книги и свернуть свой собственный код (это довольно простой алгоритм для кодирования ).

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

1 голос
/ 25 февраля 2011

Не ясно, что вы пробовали.

Этот выглядит вероятным для сегментов как таковых.

Итак, все, что вам нужно сделать, это проверить все пары ребер. Я хотел бы реализовать это в первую очередь, прежде чем пытаться оптимизировать.

Возможно, существует оптимизация при рассмотрении вектора от одного центроида к другому и только при рассмотрении ребер, которые в некотором смысле находятся в этом направлении.

0 голосов
/ 25 февраля 2011

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

...