Алгоритм решения дублирующих задач в процессе поиска для динамической генерации сетки - PullRequest
0 голосов
/ 11 марта 2019

Предположим, что размер двумерного массива 513 * 513 является значением координаты.

Я хочу динамически генерировать сетку, соединяя координаты одного и того же значения.

Значение двумерного массива генерируется случайным образом.

Используя алгоритм bfs, была введена вершина того же потока.

И чтобы создать сетку, соединив три соседние точки, поиск одного и того же значения среди восьми точек в соседнем направлении занимает слишком много времени.

Это, похоже, произошло, включая избыточность.

Я хочу, чтобы вы поделились идеями для решения проблемы избыточности.

Ниже приведен весь исходный код, функция CreateTriangle () вызывает дублирование.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class SegmentationMeshCreator : MonoBehaviour {
    // This first list contains every vertex of the mesh that we are going to render
    public List<Vector3> newVertices = new List<Vector3>();

    // The triangles tell Unity how to build each section of the mesh joining
    // the vertices
    public List<int> newTriangles = new List<int>();

    // The UV list is unimportant right now but it tells Unity how the texture is
    // aligned on each polygon
    public List<Vector2> newUV = new List<Vector2>();


    // A mesh is made up of the vertices, triangles and UVs we are going to define,
    // after we make them up we'll save them as this mesh

    // Start is called before the first frame update
    private Mesh mesh;

    public Queue<Node> SegNode = new Queue<Node>();


    private bool[,] visit = new bool[513, 513];


    private int[] dx = new int[4] { 0, 1, -1, 0 };
    private int[] dy = new int[4] { 1, 0, 0, -1 };

    // 8 - direction
    private int[,] fx = new int[8, 2] { { -1, 0 }, { -1, 0 }, { 1, 0 }, { 1, 1 }, 
                                        { -1, 0 }, { -1, 0 }, { 0, 1 }, { 0, 1 } };
    private int[,] fy = new int[8, 2] { { -1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 },
                                        { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, 1 } };

    public struct Node
    {
        public int x, y, color;

        public Node(int x, int y, int color)
        {
            this.x = x;
            this.y = y;
            this.color = color;
        }
    }

    void bfs(int r, int c, int color, int[][] pixel)
    {
        Queue<Node> q = new Queue<Node>();
        q.Enqueue(new Node(r, c, color));

        while (q.Count > 0)
        {
            Node curNode = q.Dequeue();
            SegNode.Enqueue(curNode);
            for (int i = 0; i < 4; i++)
            {
                int tr = curNode.x + dx[i];
                int tc = curNode.y + dy[i];

                if (tr >= 0 && tr < 513 && tc >= 0 && tc < 513)
                {
                    if (!visit[tr, tc] && pixel[tr][tc] == color)
                    {
                        visit[tr, tc] = true;
                        q.Enqueue(new Node(tr, tc, color));

                        newVertices.Add(new Vector3(tr, tc, 5));
                    }
                }
            }
        }
    }

    void CreateTriangle()    
    {
        int index = 0;
        while (SegNode.Count > 0)
        {

            Node curNode = SegNode.Peek();
            for (int i = 0; i < 8; i++)
            {
                var a = SegNode.Any(o => o.x == curNode.x + fx[i, 0] && o.y == curNode.y + fy[i, 0] && o.color == curNode.color);
                var b = SegNode.Any(o => o.x == curNode.x + fx[i, 1] && o.y == curNode.y + fy[i, 1] && o.color == curNode.color);

                if(a && b)
                {
                    Node nextNode = new Node(curNode.x + fx[i, 0], curNode.y + fy[i, 0], curNode.color);
                    Node nextNode2 = new Node(curNode.x + fx[i, 1], curNode.y + fy[i, 1], curNode.color);

                    newTriangles.Add(SegNode.ToArray().ToList().IndexOf(curNode) + index);
                    newTriangles.Add(SegNode.ToArray().ToList().IndexOf(nextNode) + index);
                    newTriangles.Add(SegNode.ToArray().ToList().IndexOf(nextNode2) + index);
                }
            }
            index++;
            SegNode.Dequeue();
        }
    }

    public void createMesh(int[][] pixel)
    {
        for (int r = 0; r < 513; r++)
        {
            for (int c = 0; c < 513; c++)
            {
                if (!visit[r, c] && pixel[r][c] != 0)
                {
                    newVertices.Add(new Vector3(r, c, 5));
                    bfs(r, c, pixel[r][c], pixel);

                }
            }
        }
        CreateTriangle();


        _ShowAndroidToastMessage("Create a Mesh");

        mesh = GetComponent<MeshFilter>().mesh;

        mesh.Clear();
        mesh.vertices = newVertices.ToArray();
        mesh.triangles = newTriangles.ToArray();
        mesh.uv = newUV.ToArray(); // add this line to the code here
        //mesh.Optimize();
        mesh.RecalculateNormals();
    }

    // Use this for initialization
    void Start () {
           createMesh(pixel);           // int pixel[][]
    }
}

Когда красная точка является контрольной точкой, как показано на рисунке выше, возникает проблема дублирования, которая создает еще три меша для тех же точек во время 8-стороннего поиска.

enter image description here

Если вам интересен мой проект, вы можете обратиться к моему вопросу раньше.

Как динамически создать сетку в единстве

Чтобы найти объекты с одинаковым значением, используя Queue.contains () в C #, Unity

1 Ответ

0 голосов
/ 11 марта 2019

Поскольку в createMesh() вы перебираете точки сначала по строке и по столбцу, я предполагаю для точки x, что вы уже создали все возможные треугольники для точек выше x и точки, оставшейся от x.

Тогда вам нужно только проверить, создает ли x треугольник с точками ниже x и справа от x.

...