Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 对多边形进行排序';用于绘图的s点_Algorithm_Sorting_Math_Polygon - Fatal编程技术网

Algorithm 对多边形进行排序';用于绘图的s点

Algorithm 对多边形进行排序';用于绘图的s点,algorithm,sorting,math,polygon,Algorithm,Sorting,Math,Polygon,我有一个矩阵(0表示无,1表示地形),代表我游戏中的一个等级。矩阵对应于我的屏幕被分割成的网格,并指示我的地形走向 我的地形实际上是由网格内每个块角上的4个点组成的。当您有多个连接的块时,我使用合并单元算法来删除重复点和任何内部点。结果是,我得到了一个点列表,这些点只表示多边形的外边缘 要画这个多边形,我需要点按某种顺序(顺时针或逆时针)排列,这样每个点后面都有它的相邻点。显然,第一点和最后一点必须是邻居。因为这些都在一个网格中,所以我知道相邻点之间的确切距离 问题是,我很难想出一个算法,让我“

我有一个矩阵(0表示无,1表示地形),代表我游戏中的一个等级。矩阵对应于我的屏幕被分割成的网格,并指示我的地形走向

我的地形实际上是由网格内每个块角上的4个点组成的。当您有多个连接的块时,我使用合并单元算法来删除重复点和任何内部点。结果是,我得到了一个点列表,这些点只表示多边形的外边缘

要画这个多边形,我需要点按某种顺序(顺时针或逆时针)排列,这样每个点后面都有它的相邻点。显然,第一点和最后一点必须是邻居。因为这些都在一个网格中,所以我知道相邻点之间的确切距离

问题是,我很难想出一个算法,让我“走”周围的多边形边缘,而把点的顺序。我认为应该有一种方法来利用这样一个事实,即我有表示几何体的矩阵,这意味着只有一种可能的方法来绘制多边形(即使它是凹的)

我尝试了几种使用贪婪型算法的方法,但似乎找不到一种方法来知道,在每种情况下,我想朝哪个方向旅行。考虑到任何特定点最多可以有3个相邻点(第四个不包括在内,因为它是“起点”,这意味着我已经对其进行了排序),我需要一种知道移动方式的方法

更新 我一直在尝试的另一种方法是按点的X(带Y的分界线)对点进行排序,这给了我最上面/最左边的边。这也保证了我是从外缘开始的。然而,我仍在努力寻找一种算法,以保证我留在外面而不跨越

以下是一个示例矩阵:

0 0 0 0 0 0 0 0 0 0

0 0 1 1 1 0 0 0 0 0 0

0 0 0 0 1 0 0 0 0 0

0 0 0 0 1 1 0 0

对应于此(黑点代表我的点):

我想有不同的方法可以做到这一点,我想对于对角线连接的单元被计算为不同轮廓的情况,有一种非常简单的方法:

你只需要保持牢房和角落的方向。例如,您从某个地球单元的右上角开始(它假设上单元或右单元,或者如果它是bourder,则两者均为零),并希望顺时针移动

如果右边的单元格是“地”,则将当前单元格更改为“地”,并将“角”更改为左上角(即同一点)。然后进入下一个迭代

在另一种情况下,若你们从某个地球单元的右上角开始,想顺时针走。如果右边的单元格不是地,则不更改当前单元格,也不更改右下角(这是下一个点)

所以你们也有其他三个可能的角点的对称情况,你们可以进入下一个迭代,直到回到起点

这是我编写的伪代码,它使用与图片相同的索引,并假设边界上的所有单元格都是自由的,否则需要检查索引id是否超出范围

我还需要额外的数组,它的尺寸几乎与矩阵相同,用来标记处理过的轮廓,它需要比矩阵宽1个单元格,因为我要标记垂直线,每条垂直线的右边应该有单元格的坐标。请注意,当您需要标记垂直线时,上面只描述了2种情况

    int mark[,] = new int[height,width+1]       
    start_i = i = 0;
    start_j = j = 0;
    direction = start_direction = top_left;
    index = 0;

    //outer cycle through different contours
    while(true)
    {
      ++index;
      //scanning for contours through all the matrix
      //continue from the same place, we stopped last time
      for(/*i = i*/; i < n; i++)
      {
        for(/*j = j*/; j < n; j++)
        {
           //if we found earth
           if(m[i,j] == 1)
           {
               //check if previous cell is nothing
               //check if line between this and previous contour doesn't already added
               if(m[i,j - 1] == 0 && mark[i,j] == 0)
               {
                   direction = bottom_left;
                   break;
               }

               //the same for next cell
               if(m[i,j + 1] == 0 && mark[i,j+1] == 0)
               {
                   direction = top_right;
                   break;
               }
           }
        }
        //break if we found contour
        if(i != start_i || j != start_j)
          break;
      }

      //stop if we didn't find any contour
      if(i == start_i && j == start_j)
      {
        break;
      }

      polygon = new polygon;
      start_i = i;
      start_j = j;
      start_direction = direction;

      //now the main part of algorithm described above
      do
      {
        if(direction == top_left)
        {
           if(n(i-1,j) == 1)
           {
              direction = bottom_left;
              position = (i-1,j)
           }
           else
           {
              direction = top_right;
              polygon.Add(i,j+1);       
           }
        }
        if(direction == top_right;)
        {
           if(n[i,j + 1] == 1)
           {
              direction = top_left;
              position = (i,j + 1)
           }
           else
           {
              direction = bottom_right;
              mark[i, j + 1] = index;//don't forget to mark edges!
              polygon.Add(i+1,j+1);       
           }
        } 
        if(direction == bottom_right;
        {
           if(n[i+1,j] == 1)
           {
              direction = top_right;
              position = (i+1,j)
           }
           else
           {
              direction = bottom_left;
              polygon.Add(i+1,j);       
           }
        } 
        if(direction == bottom_left)
        {
           if(n[i,j - 1] == 1)
           {
              direction = bottom_right;
              position = [i,j - 1]
           }
           else
           {
              direction = top_left;
              mark[i, j] = index;//don't forget to mark edges!
              polygon.Add(i,j);       
           }
        } 
      //and we can stop as we reached the starting state
      }while(i != start_i || j != start_j || direction != start_direction);

      //stop if it was last cell
      if(i == n-1 && j == n- 1)
      {
        break;
      }
    }
int标记[,]=新int[高度、宽度+1]
启动i=i=0;
启动_j=j=0;
方向=开始方向=左上方;
指数=0;
//通过不同轮廓的外循环
while(true)
{
++指数;
//通过所有矩阵扫描轮廓
//从同一个地方继续,我们上次停了下来
对于(/*i=i*/;i  ...
  //continue from the same place, we stopped last time
  for(/*i = i*/; i < n; i++)
  {
    for(/*j = j*/; j < n; j++)
    {
       if(mark[i,j] != 0)
       {
           if(stack.top() == mark [i,j])
           {
                stack.pop();
           }
           else
           {
                stack.push(mark [i,j]);
           }
       }
       //if we found earth
       if(m[i,j] == 1)
       {
           ...
while your matrix is not empty
    move to first "1" value. This is the rectangle top left corner
    from this corner, extend the rectangle in x and y to maximize its surface
    store the rectangle in a list and clear all corresponding "1" values
data = [[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
        [ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 ],
        [ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0 ],
        [ 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 ],
        [ 0, 1, 1, 1, 1, 0, 0, 1, 1, 0 ],
        [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]]

rows = len(data)
cols = len(data[0])

walls = [[2*(data[r][c] != data[r][c+1]) + (data[r][c] != data[r+1][c])
          for c in range(cols-1)]
         for r in range(rows-1)]
result = []
for r in range(rows-1):
    for c in range(cols-1):
        if walls[r][c] & 1:
            i, j = r+1, c
            cycle = [(i, j)]
            while True:
                if i < rows-1 and walls[i][j-1] & 2:
                    ii, jj = i+1, j
                    walls[i][j-1] -= 2
                elif i > 0 and walls[i-1][j-1] & 2:
                    ii, jj = i-1, j
                    walls[i-1][j-1] -= 2
                elif j < cols-1 and walls[i-1][j] & 1:
                    ii, jj = i, j+1
                    walls[i-1][j] -= 1
                elif j > 0 and walls[i-1][j-1] & 1:
                    ii, jj = i, j-1
                    walls[i-1][j-1] -= 1
                else:
                    break
                i, j = ii, jj
                cycle.append((ii, jj))
            result.append(cycle)
result = []
index = [[-1] * cols for x in range(rows)]
for r in range(rows-1):
    for c in range(cols-1):
        if walls[r][c] & 1:
            i, j = r+1, c
            cycle = [(i, j)]
            index[i][j] = 0
            while True:
                if i > 0 and walls[i-1][j-1] & 2:
                    ii, jj = i-1, j
                    walls[i-1][j-1] -= 2
                elif j > 0 and walls[i-1][j-1] & 1:
                    ii, jj = i, j-1
                    walls[i-1][j-1] -= 1
                elif i < rows-1 and walls[i][j-1] & 2:
                    ii, jj = i+1, j
                    walls[i][j-1] -= 2
                elif j < cols-1 and walls[i-1][j] & 1:
                    ii, jj = i, j+1
                    walls[i-1][j] -= 1
                else:
                    break
                i, j = ii, jj
                cycle.append((ii, jj))
                ix = index[i][j]
                if ix >= 0:
                    # closed a loop
                    result.append(cycle[ix:])
                    for i_, j_ in cycle[ix:]:
                        index[i_][j_] = -1
                    cycle = cycle[:ix+1]
                index[i][j] = len(cycle)-1