Найти медиальную ось многоугольника с помощью C#

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

alt текст http://www.ndl.kiev.ua/downloads/center_line.png

согласно тому, что я прочитал, то, что мне нужно, может быть получено с помощью алгоритма построения 2D-диаграммы Вороного для сегментов.

Я нашел c# - версию алгоритма Вороного на codeplex (FortuneVoronoi) и после применения моего многоугольника к нему, я заканчиваю это:

alt текст http://www.carbonatlas.com/geonotes/gaia_voronoi.png

зеленый полигон. Оранжевые-вершины Вороного, а черные линии-края вороного.

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

Я был бы признателен за любую помощь ты можешь предложить.

3 ответов


одно простое решение было бы, как предложено в комментариях:

  1. постройте триангуляцию Делоне вершин многоугольника.
  2. определите вершины Вороного внутри многоугольника (см. http://en.wikipedia.org/wiki/Point_in_polygon)
  3. выведите ребра Вороного, соединяющие две внутренние вершины Вороного.

Если у вас есть огромные данные, пересечения могут быть довольно дорогостоящими.

тогда вы могли бы сделать похожий подход, как в вопрос и данное решение может работать и на вас. Как бы я это сделал:--1-->

  1. постройте триангуляцию Делоне вершин многоугольника.
  2. вставьте среднюю точку каждого ребра многоугольника, которое не покрыто ребром Делоне. Сделайте это рекурсивно, пока все ребра многоугольника не будут покрыты ребрами Делоне.
  3. отметьте все ребра Делоне, которые соответствуют многоугольнику край.
  4. извлеките медиальную ось, используя шаги 3.-5. в данное решение

PS. Обратите внимание, что оба решения дают некоторые приближение медиальной оси, вычисляя его точно гораздо дороже, но как тизер... вы можете получить такие результаты для черных входных выборочных точек:

medial axis


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


Вау. Я собираюсь выйти на конечности здесь и предположить, что, возможно, алгоритм путаются внутри и снаружи многоугольника. Когда вы определяете ребра и вершины исходного полигона, вы должны убедиться, что они определены таким образом, что "внутри" всегда находится что-то вроде "правила правой руки". Просто глядя на многоугольник в правом нижнем углу, кажется, что край вашего многоугольника фактически пересекает себя. Возможно, алгоритм видит, что раздел, и другие, как "наизнанку". То же самое в левом нижнем углу.

Это мое внутреннее чувство, что алгоритм, похоже, не может определить, какое направление внутри и что снаружи.

Я думаю, что наивным подходом было бы отфильтровать все "узлы" Ворони, которые находятся вне полигона, однако я не думаю, что это будет выглядеть. При более близком рассмотрении диаграммы, похоже, что каждый узел имеет 3 ребра, которые соединяют его с другими узлами. Возможно, вы можете отфильтровать узлы, где любой из 3 ребер соединен с узлами вне полигона. Это сработает?