顺时针排序一组点并确保连接点的路径关闭的算法

时间:2016-03-16 04:31:38

标签: algorithm computational-geometry path-finding convex-hull

我一直在以不同的方式解决这个问题,经过一个月的努力,我认为现在是时候让新鲜的眼睛看一看。我正在尝试制作一个图像缩放应用程序,用于重新调整8位精灵的大小并将它们转换为矢量图像。到目前为止,我的工作是这样的;它拍摄图像,将其分解为形状(具有相同颜色的相邻像素的区域),然后将形状中的每个像素替换为四个像素:

private Point[] expand(int x, int y){
    x *= factor;
    y *= factor;
    return new Point[]{new Point(x+half_factor,y), new Point(x+factor,y+half_factor),
            new Point(x+half_factor, y+factor), new Point(x,y+half_factor)};
}

将四个点中的每一个放入2D布尔数组中:

private void placePoint(int x, int y){
    table[x][y] = !table[x][y];
    extrema(x,y);
}

单个形状的结果如下所示:

enter image description here

现在我想把所有这些点(减去内部的点)变成一个多边形,我尝试了很多不同的解决方案,最近我一直试图找到最近的邻居,直到它开始,但我尝试的每个算法都失败了。对于这个特殊的例子,它到达右下方的goomba是颠倒的并且在左边的像素簇中搞砸了。该程序认为路径已完成,并从那里到左上角创建一条线,完全忽略左下象限中的点。

enter image description here

这就是我想要的样子:

enter image description here

以下是一些在我的情况下总是正确的事情,可能有助于找到有效的算法:

  1. 所有点列表中的第一个点是最外面路径的一部分
  2. 最外层路径中的每个点都有一个相邻的C单位或远离它的√C单位
  3. 最外面的路径将始终是一条封闭的路径
  4. 非常感谢任何帮助!

    更新

    我已经尝试了下面的所有解决方案和建议并取得了一些进展,但我仍然无法获得所需的输出。

    ORIGINAL:

    enter image description here

    输出:

    enter image description here

    最终更新:

    它现在有效,只需解决小错误!

    enter image description here

2 个答案:

答案 0 :(得分:2)

我会尝试使用经典轮廓跟踪算法的修改版本。 http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/ray.html

修改包括水平/垂直移动采用两个像素步长(而不是标准版本中的一个)。

要查找所有轮廓,请扫描整个图像,直到您遇到一个像素;按照该轮廓,关闭所有像素。然后继续扫描离开的位置。

答案 1 :(得分:1)

处于较高水平,

  1. 填充填充以查找连接的像素集。
  2. 应用边界运算符以获得嵌入的平面图。
  3. 找到外表。
  4. 步骤2和3是新的。步骤2通过放置两个半边来完成,其中集合中的像素邻近不在集合中的像素,每个方向一个。例如,

    ***
    * *
    ***
    * *
    

    变成

    ._._._.
    |* * *|
    . ._. .
    |*| |*|
    . ._. .
    |* * *|
    . ._. .
    |*| |*|
    ._. ._.
    

    其中每个_|表示两个半边,每个方向一个。对于每个点.,收集指向它的半边,并按逆时针顺序从每个这样的半边到下一个边做一个指针。每个半边也应该指向相反方向的半边缘。

    步骤3通过如下遍历完成:给定半边,以逆时针方向找到指向同一点的下一个半边,然后重复找到与该半边相对的半边。这将追溯其中一个面孔。如果您想要最外层,请从集合中最顶层像素的顶部边界开始。