确定平面上的孔

时间:2015-08-05 07:56:57

标签: c# algorithm geometry plane

我有一个点x和h的集合,其中h代表一个平面上的洞。我需要确定每个洞的边界(作为点的集合)。做这个的最好方式是什么?看起来很简单,但我正在努力找出一种有效的方法。

x x x x x x x x x x x x x 
x h h h h x x x x x x x x 
x h h h x x x x x x x x x 
X h h x x x h h x x x h h
x x x x x x x x x x x x x

要明确 - 我需要点数' h'代表每个' h'的集合的边界。并排除任何内部'。

编辑(上下文):

我正在开发一个由如上所述的许多块构成的游戏。对于每个块,我需要确定表示平面上的孔的点,这样我就可以为每个孔的底部构建一个对撞机。我在C#和Unity3D中这样做。

编辑2:

边缘不被视为边界点,因此边缘旁边的孔需要是非闭合多边形,即线段。

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

我认为您正在寻找的算法位于图像处理区域。 尝试寻找轮廓发现的不同算法。 这是一个开始: http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/alg.html

答案 1 :(得分:1)

我做了类似这样的事情,很多年前在哥斯达黎加找到了不同丛林丛林的边界。

你有两个问题,一个是将h从一个洞与另一个洞中的h分开。如果他们在外面或不在外面,第二个是锻炼。

第二个问题首先,如果'h'的邻居是'x',那么它就在外面。

第一个问题,我解决了它有点像洪水填充。数组上的栅格,如果它是'x'继续。如果是'h',则将其标记为1,然后找到所有'h'的邻居,并将它们标记为'1'。你可以递归地做。

Label(Point p, List<Point> points)
{
  if(map[p]=='h' && !points.Contain(p))
  {
    points.Add(p);
    foreach neighbour of p
       Label(neighbour, points);
  }    
}

没有承诺它是完美的,但我希望你看到我要去的地方。 完成后,点将包含洞中的所有连续点。

完成后,继续使用光栅,但将下一个'h'标记为'2'。当它完成后,你将拥有

x x x x x x x x x x x x x 
x 1 1 1 1 x x x x x x x x 
x 1 1 1 x x x x x x x x x 
X 1 1 x x x 2 2 x x x 3 3
x x x x x x x x x x x x x

当完成后再次检查点,任何不是'x'且没有'x'的邻居都在一个洞内。

至于效率方面,我是用C#做的,它在大约3毫秒内完成了哥斯达黎加的所有工作。

我实际上喜欢Moore-Neighbor Tracing算法Eugene发布了一个比这更好的链接。当我最初这样做的时候,我也需要所有的内部点,而我刚刚为此问题添加了“丢掉内部位”。只要您对邻居的含义有一个简单的了解,就可以更加优雅地走在外面。

答案 2 :(得分:1)

根据您的定义,当且仅当

时,点是h的区域的边界点
  1. 本身就是h和
  2. 至少有一个邻居是x。
  3. 因此迭代所有点,只考虑h并丢弃仅由h包围的所有点。

    您没有定义整个区域边界的h是否被视为h区域的边界点。