Найти недостающие точки в N-мерной сетке

#algorithm #grid #point #convex

#алгоритм #сетка #точка #выпуклый

Вопрос:

У меня есть N-мерная (обычная) сетка с данными, которая не заполняет ее объем полностью, но должна быть выпуклой. Так, например, в 2D это нормально (1 = существует, 0 = отсутствует):

0011111100
0111111110
1111111111
0011111100
0000011100

Но это не:

0011111100
0111101110
1111111111
0011111000
0000011100

Я хочу найти дополнительные нули во втором примере (выделены жирным шрифтом). И я хочу сделать это более чем в 2 измерениях.

Единственный способ, который я могу придумать сейчас, — это получить все возможные координаты в N-1 измерениях и проверить в N-м измерении, является ли оно выпуклым, что просто означает поиск первой и последней точек данных в этом измерении и проверку, отсутствует ли какая-либо точка между ними. Но мне пришлось бы делать это в каждом измерении и для каждого среза в этом измерении.

Должно быть более простое решение, верно?

Ответ №1:

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

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

Комментарии:

1. Спасибо, взгляну на предоставленные вами ссылки.

2. Это не проблема обработки сетки, это проблема, связанная только с вокселями. Алгоритмы с выпуклой оболочкой являются абсолютным излишеством для чего-то подобного. Здесь можно использовать простой подход, основанный на заливке.

3. Попробуйте использовать simple flood-fill-based approach на примере, приведенном OP.

Ответ №2:

Чтобы легко решить эту проблему, рассмотрим противоположную задачу: «Как можно найти пространство, окружающее фигуру?»

Если вы знаете, как заполнить все пространство, окружающее фигуру, то все пиксели или воксели, которые не являются частью этого пустого пространства, должны быть частью выпуклой оболочки. В следующем примере мы:

  1. заполните все окружающее 0 пространство -
  2. заменить - на 0 и 0 на 1 (в результате получается выпуклая оболочка)
  3. XOR с исходной моделью
 01110        -111-        01110        00000
11010   ->   1101-   ->   11110   ->   00100
11111        11111        11111        00000
  

В конечном результате a 1 теперь представляет собой замкнутое пустое пространство. Обратите внимание, что - это может быть представлено как 2 или 3 , чтобы это сработало, и нам временно понадобилось бы два бита на воксель, а не только один.

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

Реализация второго и третьего шага должна быть тривиальной.

Избегание «тролеанской» логики

Также все это можно сделать только с помощью логической логики, поэтому третьего - значения нет. Чтобы сделать это, нам пришлось бы:

  • flood- заполнить нули во входном массиве с 1 вместо -
  • для каждого заполняемого вокселя запишите 1 в отдельный выходной буфер

Затем первый шаг даст нам результат:

 10001
00001
00000
  

Теперь нам просто нужно немного перевернуть этот буфер, чтобы получить выпуклую оболочку.

Комментарии:

1. Я тоже подумал то же самое, когда впервые увидел сообщение. Можете ли вы попробовать использовать эту технику на примере, опубликованном OP? Это работает для 0, окруженного всеми единицами, но не для нулей внутри выпуклой оболочки, но не окруженных единицами со всех сторон.

2. Это то, что я думал. Я не понимаю, как это будет работать для недостающих точек на краю заполненной области.