围绕2D网格形状的周长

时间:2019-05-24 02:22:27

标签: algorithm multidimensional-array geometry

给定grid[x,y]形式的正方形单元的2D网格,我想要一种算法,该算法产生形成形状外围的有序点集。换句话说,该算法将围绕形状的角部生成一条外围路线,如下图所示:

我看过诸如this之类的帖子(上面的图片在那里),我可以找到形状的角。我有两个问题:1)一旦找到形状的角,如何遍历它们以找到正确的(有效的)路线? 2)这样找到路线的方法是否会始终产生顺时针/逆时针路线?对我来说,顶点的顺序是顺时针/逆时针并不重要,只要它们一致地顺时针或逆时针即可。

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

这假定每个回路对每个角的访问不会超过一次。换句话说,没有两个灰色和两个黑色的角落,两个灰色正方形位于不相邻的角落。enter image description here

掌握一些数据结构,可以让您快速:

  • 获取由给定的x坐标按y坐标排序的所有角的列表。
  • 获取由x坐标排序的给定y坐标的所有角的列表。

这是算法:

Start with arbitrary corner c. 
        We'll say it has 3 adjacent black squares and 1 grey, and that the 
        1 grey square is in the -x,+y direction.

Choose perimeter direction. We'll say clockwise.

Determine which direction the perimeter goes in that corner. This can be done 
        by looking at the direction of the adjacent tile there's only 1 color of.

        In our example, the perimeter goes -x/+y

Determine if c is concave or convex. 
        Convex has 3 adjacent black squares, concave has 3 adjacent grey squares. 
        In our example, c is convex because it has 3 adjacent black squares.

Knowing the direction of the perimeter from that corner and if it's concave or 
        not tells us what direction is clockwise:

    clockwise at convex +x/-y is +x,
    clockwise at convex +x/+y is +y,
    clockwise at convex -x/-y is -y,
    clockwise at convex -x/+y is -x 

If it is concave clockwise goes the other direction.  

(obviously if the desired perimeter direction is counterclockwise, it's the opposite)

Because c in our example is a convex corner and it goes -x/+y, 
        that means clockwise is along the x wall, so set current_axis = x, 

It goes negative in that direction so set current_direction = -1
        Otherwise, it would be set to 1


create list ordered_corner_list that only contains c

While length of ordered_corner_list < number of corners:

    Get list of all corners with same value of current_axis as c ordered by the other axis. 
            e.g. for the first iteration, get same x value as c ordered by y

    if current_direction = -1:
        find node with the next lowest ordered value from c.
                e.g. for the first iter, get corner with next lowest x from c

    else:
        find node with the next highest ordered value from c

    assign that node to c
    append c to ordered_corner_list

    set current_axis = the other axis  
            e.g. for the first iteration, current_axis = y here

    set current_direction to the direction that corner goes in the current_axis