Я пытаюсь найти значения координат с одинаковыми значениями. И я собираюсь связать три значения координат.
Я делаю это, чтобы сделать сетку в Unity.
Эти же координаты я сначала нашел методом bfs.
И есть проблема с попыткой соединить три соседние координаты.
Я сделал следующее, чтобы узнать, есть ли соседние точки в восьми направлениях.
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 } };
void CreateTriangle()
{
int index = 0;
while (SegNode.Count > 0)
{
Node curNode = SegNode.Peek();
for (int i = 0; i < 8; i++)
{
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);
Debug.Log("CurNode " + curNode.x + " , " + curNode.y +
" NextNode " + nextNode.x + " , " + nextNode.y +
" NextNode2 " + nextNode2.x + " , " + nextNode2.y);
if (SegNode.Contains(nextNode) && SegNode.Contains(nextNode2))
{
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();
}
}
явно есть пункт про (0,1) (1,0), но я не могу найти его с помощью Queue.Contains()
Может быть, Contains() не распознает его, потому что я использовал [new] для создания нового объекта. Как я могу найти объект?
Вот мой полный код
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class MeshCreator : 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
private Mesh mesh;
// Start is called before the first frame update
private int[,] pixel = new int[15, 15] {
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 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 },
{ 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 2, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
private bool[,] visit = new bool[15, 15];
private int[] dx = new int[4] { 0, 1, -1, 0 };
private int[] dy = new int[4] { 1, 0, 0, -1 };
public int idx = 0;
public class Node
{
public int x, y, color;
public Node(int x, int y, int color)
{
this.x = x;
this.y = y;
this.color = color;
}
}
public Queue<Node> SegNode = new Queue<Node>();
void bfs(int r, int c, int color)
{
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 < 15 && tc >= 0 && tc < 15)
{
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, 0));
}
}
}
}
}
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 } };
void CreateTriangle()
{
int index = 0;
while (SegNode.Count > 0)
{
Node curNode = SegNode.Peek();
for (int i = 0; i < 8; i++)
{
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);
Debug.Log("CurNode " + curNode.x + " , " + curNode.y +
" NextNode " + nextNode.x + " , " + nextNode.y +
" NextNode2 " + nextNode2.x + " , " + nextNode2.y);
if (SegNode.Contains(nextNode) && SegNode.Contains(nextNode2))
{
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();
}
}
void Start()
{
//int result = 0;
for (int r = 0; r < 15; r++)
{
for (int c = 0; c < 15; c++)
{
if (!visit[r, c] && pixel[r, c] != 0)
{
newVertices.Add(new Vector3(r, c, 0));
bfs(r, c, pixel[r, c]);
//result++;
}
}
}
CreateTriangle();
mesh = GetComponent<MeshFilter>().mesh;
}
}





классы ссылочные типы. Это означает, что ваша очередь SegNode на самом деле содержит не значения, а использованная литература для экземпляров Node.
Как вы уже сказали, ваша проверка Contains не работает так, поскольку вы проверяете, существует ли в очереди одна и та же ссылка на точно такой же экземпляр Node.
Вместо этого вы можете просто сделать свой Nodeтип значения, изменив его с class на struct
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;
}
}
чем ваш чек
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);
Debug.Log("CurNode " + curNode.x + " , " + curNode.y +
" NextNode " + nextNode.x + " , " + nextNode.y +
" NextNode2 " + nextNode2.x + " , " + nextNode2.y);
if (SegNode.Contains(nextNode) && SegNode.Contains(nextNode2))
{
//...
}
должно сработать.
В качестве альтернативы вы можете использовать, например. Linq ФерстОрДефаулт нравится
var nextNode = SegNode.FirstOrDefault(n => n.x == curNode.x + fx[i, 0]
&& n.y == curNode.y + fy[i, 0]);
var nextNode2 = SegNode.FirstOrDefault(n => n.x == curNode.x + fx[i, 1]
&& n.y == curNode.y + fy[i, 1]);
if (nextNode != null && nextNode2 != null)
{
// ...
}
FirstOrDefault возвращает первое совпадение, определенное предикатом, например.
n.x == curNode.x + fx[i, 0] && n.y == curNode.y + fy[i, 0]
или null, если совпадений не найдено или список/очередь пусты
в качестве более широкой альтернативы вы также можете позволить своему Node реализовать IEquatable, но это может быть немного излишним для вашего варианта использования;)