Well, I’m working with pixels right now in Unity… I was wondering if anyone could help me with this.
For example, I created an image like this:
And now I store every black pixel in a List<Point> like this:
//Think that I can get all pixels as an Color[,] array (actually, I can)
List<Point> points = new List<Point>();
for(int i = 0; i < width; ++i)
for(int j = 0; j < height; ++j)
if(colorMap[i, j] == Color.black)
points.Add(new Point(i, j));
Now I have stored all the points in a List, but with the problem that they are ordered as the image was looped out. So, now I have the question, how can I order it?
I have tried something like that:
public Shape SortDistance()
{
List<Point> vlist = vertices.ToList(), //Get all the vertices in a list
orderedList = new List<Point>(); //This will be the final list
Point fp = vlist.Find(x => x == position), //Get the first pixel that was detected before... (This is )
curPos = fp;
int maxLoops = vertices.Length * 10, //I tried to avoid freezes without luck
lp = 0;
while(vlist.Count > 0 && lp < maxLoops)
{
var clockwiseDirs = new Point[] { Point.upperLeft, Point.up, Point.upperRight, Point.right, Point.downRight, Point.down, Point.downLeft, Point.left }; //8-connectivity array
List<Point>[] neighs = new [] { new List<Point>(), new List<Point>() }; //This is a little bit confusimg, but here, the only trhing I do, is store in the first array the 4-connectivity (up, left, bottom and right) points and in the seconds the corners
foreach (Point p in clockwiseDirs)
{
int j = p.x,
k = p.y;
if (j != 0 && k != 0)
{ //If this position isn't the center...
Point nPoint = vertices.FirstOrDefault(x => x == curPos + new Point(j, k)); //Check if there is any pixel, if not return null
if (nPoint == null || nPoint == Point.zero)
continue; //And skip...
List<Point> mergedNeighs = neighs[0].Union(neighs[1]).ToList(); //If yes, merge the two arrays
if (!mergedNeighs.Contains(nPoint)) //Only for check if this points wasn't already added
if ((nPoint - curPos).sqrMagnitude == 1)
neighs[0].Add(nPoint); //If the distance is 1 it means that the position is top or left or bottom or right...
else if ((nPoint - curPos).sqrMagnitude == 2)
neighs[1].Add(nPoint); //If it's 2, it means the corners
}
}
bool n1 = neighs[0].Count > 0, //Sides
n2 = neighs[1].Count > 0; //Corners
if (n1 || n2)
{ //If it has neighbors
List<Point> mergedNeighs = n1 && n2 ? neighs[0].Union(neighs[1]).ToList() : neighs[n1 && !n2 ? 0 : 1]; //There we have to sleect what we want, depending on the neighbors found before
foreach (Point ne in mergedNeighs) //Now we loop over them
{ //Comprobamos cada uno de los vecinos
List<Point> fPoints = new List<Point>();
if (!orderedList.Contains(ne)) //Check if the final list doesn't has this point
fPoints.Add(ne);
if (fPoints.Count == 1)
{ //If there is only one neighbor
orderedList.Add(fPoints[0]); //Add it to the fional list
vlist.Remove(curPos); //Delete it from the other list
curPos = fPoints[0]; //And set the new pos to revise
}
else
{ //If there are several neighbors
Point np = fPoints.FirstOrDefault(x => x.sqrMagnitude == 1); //We select the nearest one
foreach(Point vp in fPoints)
orderedList.Add(vp); //They are orderer, so we have to add them
vlist.Remove(curPos);
curPos = np;
}
}
}
else //If the pixel is alone remove it, impossible case??
vlist.Remove(curPos);
++lp;
}
if (lp > vertices.Length * 5)
Debug.Log("Mmmm..."); //If this goes up something is going wrong, but I have noticed it because my pc freezes
vertices = orderedList.ToArray();
return this;
}
I’m aware this is better to be in Code Review, but I don’t know, I have to optimize it, but first fix it, because I think that the while freezes, but I have small RAM size and a lot of “Shapes” to check, so I cannot know exactly where it fails, because, my PC freezes.
One option could be to make a coroutine, but my problem there is that my script is a messm and If I do this I could cause a null object reference.
If anyone could help me I would be so happy! Thanks in advance.
