使用C#查找多边形的中轴

时间:2021-10-28 08:51:19

I've been tasked to figure out how to find the centerline of a polygon. My google searches led me to believe that what I need is called the 'Medial Axis'. Like this:

我的任务是弄清楚如何找到多边形的中心线。我的谷歌搜索让我相信我所需要的是'Medial Axis'。像这样:

alt text http://www.ndl.kiev.ua/downloads/center_line.png

替代文字http://www.ndl.kiev.ua/downloads/center_line.png

According to what I've read, what I need can be produced by using a 2D Voronoi diagram construction algorithm for segments.

根据我所读到的,我可以通过使用2D Voronoi图构造算法来生成我需要的东西。

I've found a C# version of the Voronoi algorithm on codeplex (FortuneVoronoi) and after applying my polygon to it, I end up with this:

我在codeplex(FortuneVoronoi)上找到了Voronoi算法的C#版本,在将多边形应用到它之后,我最终得到了这个:

alt text http://www.carbonatlas.com/geonotes/gaia_voronoi.png

替代文字http://www.carbonatlas.com/geonotes/gaia_voronoi.png

The green is the original polygon. The orange are the Voronoi vertices and the black lines are the voronoi edges.

绿色是原始多边形。橙色是Voronoi顶点,黑色线是voronoi边缘。

I can see the makings of what I need in those vertices, but I'm unsure of the next step required to filter out all the stuff I don't need.

我可以在这些顶点看到我需要的材料,但我不确定下一步需要过滤掉我不需要的所有东西。

I'd appreciate any help you can offer.

我很感激您提供的任何帮助。

3 个解决方案

#1


One simple solution would be as suggested in the comments:

一个简单的解决方案将如评论中所建议:

  1. Build the Delaunay triangulation of the polygon vertices.
  2. 构建多边形顶点的Delaunay三角剖分。

  3. Identify the Voronoi vertices inside the polygon (see http://en.wikipedia.org/wiki/Point_in_polygon)
  4. 识别多边形内的Voronoi顶点(请参阅http://en.wikipedia.org/wiki/Point_in_polygon)

  5. Output the Voronoi edges connecting two interior Voronoi vertices.
  6. 输出连接两个内部Voronoi顶点的Voronoi边。

If you have huge data the intersections might be quite costly.

如果您有大量数据,交叉路口可能会非常昂贵。

Then you could do a similar approach like in the question, and this solution could work for you, as well. The way I would do it:

那么你可以像问题一样做一个类似的方法,这个解决方案也适合你。我会这样做的方式:

  1. Build the Delaunay triangulation of the polygon vertices.
  2. 构建多边形顶点的Delaunay三角剖分。

  3. Insert the midpoint of every polygon edge that is not covered by a delaunay edge. Do this recursively until all polygon edges are covered by Delaunay edges.
  4. 插入未被delaunay边缘覆盖的每个多边形边的中点。递归执行此操作,直到所有多边形边都被Delaunay边覆盖。

  5. Mark all Delaunay edges which correspond to a polygon edge.
  6. 标记对应于多边形边的所有Delaunay边。

  7. Extract the medial axis using steps 3.-5. in this solution
  8. 使用步骤3.-5提取中轴。在这个解决方案中

PS. Note that both solutions give some approximation of the medial axis, computing it exactly is much more costly but as a teaser... you can get results like this for the black input sample points:

PS。请注意,这两个解决方案都给出了一些近似的中轴,计算它的成本要高得多,但作为预告片...你可以得到这样的结果用于黑色输入采样点:

使用C#查找多边形的中轴

#2


A similar construct is the Straight skeleton, which can be constructed by shrinking the polygon into itself and tracing the vertices as they approach the center. This may be a little easier to construct, though it's not quite the same curve as the medial axis.

类似的构造是直骨架,可以通过将多边形收缩到自身并在顶点接近中心时跟踪顶点来构造。这可能更容易构建,尽管它与中轴的曲线不完全相同。

#3


Wow. I'm going to go out on a limb here and suggest that maybe the algorithm is confused about the inside vs. the outside of the polygon. When you define the edges and vertices of your original polygon, you have to make sure they're defined in such a way that "inside" is always found using something like the "right hand rule". Just looking at the polygon in the bottom right corner, it looks like the edge of your polygon actually crosses itself. Maybe the algorithm is seeing that section, and others, as "inside out". The same in the bottom left.

哇。我打算在这里走出去,并建议可能算法混淆了多边形的内部与外部。定义原始多边形的边和顶点时,必须确保它们的定义方式是始终使用“右手规则”之类的内容找到“内部”。只看右下角的多边形,看起来多边形的边缘实际上就是自身交叉。也许算法会将该部分和其他部分视为“由内而外”。左下角也是如此。

That's my gut feeling, that the algorithm doesn't seem to be able to determine what direction is inside and what is outside.

这是我的直觉,该算法似乎无法确定内部和外部的方向。

I think a naive approach would be to filter out all Voroni "nodes" that are outside the polygon, however, I don't think that will look. Taking a closer look at your diagram, it looks like each node has 3 edges that connect it to other nodes. Perhaps you can filter out nodes where any of the 3 edges are connected to nodes outside the polygon. Would that work?

我认为一种天真的方法是过滤掉多边形之外的所有Voroni“节点”,但是,我认为不会看起来。仔细查看您的图表,看起来每个节点有3条边连接到其他节点。也许您可以过滤掉3个边中的任何边连接到多边形外部节点的节点。那会有用吗?

#1


One simple solution would be as suggested in the comments:

一个简单的解决方案将如评论中所建议:

  1. Build the Delaunay triangulation of the polygon vertices.
  2. 构建多边形顶点的Delaunay三角剖分。

  3. Identify the Voronoi vertices inside the polygon (see http://en.wikipedia.org/wiki/Point_in_polygon)
  4. 识别多边形内的Voronoi顶点(请参阅http://en.wikipedia.org/wiki/Point_in_polygon)

  5. Output the Voronoi edges connecting two interior Voronoi vertices.
  6. 输出连接两个内部Voronoi顶点的Voronoi边。

If you have huge data the intersections might be quite costly.

如果您有大量数据,交叉路口可能会非常昂贵。

Then you could do a similar approach like in the question, and this solution could work for you, as well. The way I would do it:

那么你可以像问题一样做一个类似的方法,这个解决方案也适合你。我会这样做的方式:

  1. Build the Delaunay triangulation of the polygon vertices.
  2. 构建多边形顶点的Delaunay三角剖分。

  3. Insert the midpoint of every polygon edge that is not covered by a delaunay edge. Do this recursively until all polygon edges are covered by Delaunay edges.
  4. 插入未被delaunay边缘覆盖的每个多边形边的中点。递归执行此操作,直到所有多边形边都被Delaunay边覆盖。

  5. Mark all Delaunay edges which correspond to a polygon edge.
  6. 标记对应于多边形边的所有Delaunay边。

  7. Extract the medial axis using steps 3.-5. in this solution
  8. 使用步骤3.-5提取中轴。在这个解决方案中

PS. Note that both solutions give some approximation of the medial axis, computing it exactly is much more costly but as a teaser... you can get results like this for the black input sample points:

PS。请注意,这两个解决方案都给出了一些近似的中轴,计算它的成本要高得多,但作为预告片...你可以得到这样的结果用于黑色输入采样点:

使用C#查找多边形的中轴

#2


A similar construct is the Straight skeleton, which can be constructed by shrinking the polygon into itself and tracing the vertices as they approach the center. This may be a little easier to construct, though it's not quite the same curve as the medial axis.

类似的构造是直骨架,可以通过将多边形收缩到自身并在顶点接近中心时跟踪顶点来构造。这可能更容易构建,尽管它与中轴的曲线不完全相同。

#3


Wow. I'm going to go out on a limb here and suggest that maybe the algorithm is confused about the inside vs. the outside of the polygon. When you define the edges and vertices of your original polygon, you have to make sure they're defined in such a way that "inside" is always found using something like the "right hand rule". Just looking at the polygon in the bottom right corner, it looks like the edge of your polygon actually crosses itself. Maybe the algorithm is seeing that section, and others, as "inside out". The same in the bottom left.

哇。我打算在这里走出去,并建议可能算法混淆了多边形的内部与外部。定义原始多边形的边和顶点时,必须确保它们的定义方式是始终使用“右手规则”之类的内容找到“内部”。只看右下角的多边形,看起来多边形的边缘实际上就是自身交叉。也许算法会将该部分和其他部分视为“由内而外”。左下角也是如此。

That's my gut feeling, that the algorithm doesn't seem to be able to determine what direction is inside and what is outside.

这是我的直觉,该算法似乎无法确定内部和外部的方向。

I think a naive approach would be to filter out all Voroni "nodes" that are outside the polygon, however, I don't think that will look. Taking a closer look at your diagram, it looks like each node has 3 edges that connect it to other nodes. Perhaps you can filter out nodes where any of the 3 edges are connected to nodes outside the polygon. Would that work?

我认为一种天真的方法是过滤掉多边形之外的所有Voroni“节点”,但是,我认为不会看起来。仔细查看您的图表,看起来每个节点有3条边连接到其他节点。也许您可以过滤掉3个边中的任何边连接到多边形外部节点的节点。那会有用吗?