Эффективность алгоритма для решения вашей проблемы будет зависеть от структур данных, которые представляют вас sh. Вам может потребоваться более детально указать c о них, чтобы получить достаточно производительную процедуру.
Алгоритмы представлены неформальным образом. Для более тщательного анализа, math.stackexchange может быть более подходящим местом для запроса (или другой участник более склонен ответить ...).
Алгоритмы являются heuristi c по своей природе. Предложения 1 и 3 будут хорошо работать для сеток, кривизна локальной границы которых в основном выпуклая локально (здесь пропускается строгое математическое определение). Предложение 2 должно в меньшей степени зависеть от формы me sh (и может быть легко настроено для обслуживания форм с плохим поведением).
Предложение 1 (выпуклый корпус, 2D)
Пусть M
будет набором из меня sh точек, спроецированных на «подходящую» плоскость, как указано в предоставленной вами графике.
- Вычислите выпуклый корпус
CH(M)
из M
. - Закажите
n
точек CH(M)
по часовой стрелке относительно любой точки внутри CH(M)
, чтобы получить последовательность точек seq(P) = (p_0, ..., p_(n-1))
, где p_0
является произвольным элементом CH(M)
. Обратите внимание, что это обычно является побочным продуктом вычисления выпуклой оболочки. - Найдите самый длинный край выпуклого многоугольника, подразумеваемый
CH(M)
.
В частности, найдите k
, такое, что расстояние d(p_k, p_((k+1) mod n))
является максимальным среди всех d(p_i, p_((i+1) mod n)); 0 <= i < n
; - Рассмотрим вектор
(p_k, p_((k+1) mod n))
. Если y
координата его головы больше, чем у его хвоста (ie. Его проекция на линию ((0,0), (0,1))
направлена вверх), то ваш me sh открывается влево, в противном случае вправо.
Шаг 3 использует условие, что граница me sh будет в основном локально выпуклой. Таким образом, стороны многоугольника выпуклой оболочки в основном короткие, за исключением стороны, которая охватывает отверстие me sh.
Предложение 2 (биссектриса, 2D)
- Упорядочить точки me sh по их
x
координатам в последовательности seq(M)
. - разделить
seq(M)
на 2 половины, пусть seq_left(M)
, seq_right(M)
обозначают элементы разбиения. Повторите следующие шаги для обоих наборов точек.
3.1. Выберите случайным образом 2 точки p_0
, p_1
из набора точек.
3.2. Найдите биссектрису p_01
отрезка (p_0, p_1)
.
3.3. Проверьте, находится ли p_01
внутри меня sh.
3.4. Держите счет на неудачных тестах.
Статистически, подмножество точек me sh, которое «содержит» открытие, вызовет больше сбоев для того же заданного числа тесты запускаются на каждом разделе. Также будут работать альтернативные критерии тестирования, например. запись среднего расстояния d(p_0, p_1)
или средней длины (p_0, p_1)
участков вне me sh (оба выше на подмножестве me sh point с открытием). Отрежьте повторение шага 3, если разница в результатах испытаний между двумя половинками является «достаточно выраженной». Для форм с плохим поведением увеличьте количество повторений.
Предложение 3 (выпуклый корпус, 3D)
Только для полноты , поскольку описание вашей проблемы предполагает, что анализ эффективно выполняется в 2D.
Как и в предложении 1, вычисления могут быть выполнены в 3D. Тогда выпуклая оболочка точек me sh подразумевает выпуклый многогранник, грани которого должны быть упорядочены по площади. Выберите грань с максимальной площадью и вычислите ее нормаль, направленную наружу, которая указывает направление отверстия с точки зрения центра b-коробки.
Расчет становится более сложным, если в стороне много изменений длины минимальной ограничительной рамки me sh точек, ie. если есть плоскость, в которой происходит большая часть изменения координат точки sh. В предоставленной вами графике это будет плоскость, в которой отображаются точки me sh, при условии, что их координаты не сильно изменяются вдоль оси, перпендикулярной плоскости.
Решение состоит в том, чтобы идентифицировать такие самолет и спроецируйте на него точки sh, затем прибегните к предложению 1.