이 방법이 효과가 있다는 생각이 들지 않습니다. 나는 방금 재미로 그것을 썼고 그것에 진짜 테스트를 적용 할 수 없었다. 친절하게도 그것에 대한 시도와 의견을 주시면 감사하겠습니다.
struct pixel
{
public int R;
public int G;
public int B;
public bool Fixed;
public pixel(int r, int g, int b, bool _fixed)
{
this.R = r; this.G = g; this.B = b; this.Fixed = _fixed;
}
public int DistanceSQ(pixel px)
{
int r = this.R - px.R;
int g = this.G - px.G;
int b = this.B - px.B;
return r * r + g * g + b * b;
}
public override string ToString()
{
return string.Format("{0} {1} {2} {3}", this.R, this.G, this.B, this.Fixed);
}
public override int GetHashCode()
{
return this.R.GetHashCode()^this.G.GetHashCode()^this.B.GetHashCode();
}
public override bool Equals(object obj)
{
pixel px = (pixel)obj;
return this.R == px.R && this.G == px.G && this.B == px.B;
}
}
static void sort(pixel[,] img)
{
List<pixel> lst = new List<pixel>();
foreach (pixel px in img)
if (!px.Fixed)
lst.Add(px);
int rows = img.GetLength(0);
int cols = img.GetLength(1);
while (lst.Count > 0)
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++)
if (!img[row, col].Fixed)
{
pixel[] neighbors = getFixedNeighbors(img, row, col, rows, cols).ToArray();
int min = int.MaxValue;
pixel nearest = new pixel();
foreach (pixel n in lst)
{
int dist = neighbors.Select((a) => a.DistanceSQ(n)).Sum();
if (dist < min)
{
min = dist;
nearest = n;
}
}
nearest.Fixed = true;
img[row, col] = nearest;
lst.Remove(nearest);
if (lst.Count == 0)
return;
}
}
private static IEnumerable<pixel> getFixedNeighbors(pixel[,] img, int row, int col, int rows, int cols)
{
for (int r = Math.Max(0, row - 1); r < Math.Min(row + 2, rows); r++)
for (int c = Math.Max(0, col - 1); c < Math.Min(col + 2, cols); c++)
if (img[r, c].Fixed)
yield return img[r, c];
}
//test
{
bool b0 = false; bool b1 = true;//for easy editing
{
pixel[,] img = new pixel[3, 4];
img[0, 0] = new pixel(0, 0, 0, b1); img[1, 0] = new pixel(0, 1, 0, b0); img[2, 0] = new pixel(0, 2, 0, b1);
img[0, 1] = new pixel(1, 0, 0, b0); img[1, 1] = new pixel(1, 1, 0, b0); img[2, 1] = new pixel(1, 2, 0, b0);
img[0, 2] = new pixel(2, 0, 0, b0); img[1, 2] = new pixel(2, 1, 0, b0); img[2, 2] = new pixel(2, 2, 0, b0);
img[0, 3] = new pixel(3, 0, 0, b1); img[1, 3] = new pixel(3, 1, 0, b0); img[2, 3] = new pixel(3, 2, 0, b1);
sort(img);
}
{
pixel[,] img = new pixel[3, 4];
img[0, 0] = new pixel(0, 0, 0, b1); img[1, 0] = new pixel(0, 1, 0, b0); img[2, 0] = new pixel(0, 2, 0, b1);
img[0, 1] = new pixel(2, 0, 0, b0); img[1, 2] = new pixel(2, 1, 0, b0); img[2, 2] = new pixel(2, 2, 0, b0);
img[0, 2] = new pixel(1, 0, 0, b0); img[1, 1] = new pixel(1, 1, 0, b0); img[2, 1] = new pixel(1, 2, 0, b0);
img[0, 3] = new pixel(3, 0, 0, b1); img[1, 3] = new pixel(3, 1, 0, b0); img[2, 3] = new pixel(3, 2, 0, b1);
sort(img);
}
}
코드는 간단합니다. 평가되지 않은 항목을 목록에 보관하고 위치를 찾으면 각 항목을 제거합니다. 위치에 대해 선택해야하는 색상을 결정할 때 최소 제곱 거리의 합이있는 색상이 선택됩니다. Sqrt는 비교를 위해서만 필요하므로 필요하지 않습니다.
"정렬"은 고정되지 않은 픽셀의 위치를 변경하는 주요 기능입니다. 이 함수에 대한 입력은 픽셀의 행 - 열 배열입니다. "sort"함수는이 배열을 변경합니다.
ok 나는 게임을하지는 않았지만 게임의 앞 표지에서 부드러운 마무리가 될 수있는 색상의 방향이 4 가지 인 것처럼 보입니다 ... 게임에서 4 가지 조합을 모두 허용하는지 궁금합니다. 아니면 하나의 솔루션 만 존재하도록 항상 고정 된 블록이 있습니까? –
@TheoWalton 항상 하나의 솔루션 만 존재하도록하는 고정 블록이 있습니다. –
참조한 이미지는 다양한 색조와 채도가 혼합 된 것처럼 보입니다. 채도는 이미지 중심에서 방사상으로 이미지 테두리로 증가합니다. 색조는 이미지 중심 주위의 각도에 따라 다릅니다. 이 방법으로 극좌표에서 2 차원을 갖게됩니다. 검은 색 점이 찍힌 색상 패치는 이제 불규칙한 격자 위에 보간을위한 제어점을 선언합니다. 그러나, 그 게임에서 다른 샘플 이미지를 보지 않고도, 색 그라디언트가 항상 위에서 언급 한 극좌표를 따를 지 여부는 여전히 열려 있습니다. –