static public DistanceEntry[,] GetDistanceMap(bool[,] Mask)
{
int Width = Mask.GetLength(0);
int Height = Mask.GetLength(1);
var DistanceMap = new DistanceEntry[Width, Height];
var Row = new DistanceEntry[Width];
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
DistanceMap[x, y] = new DistanceEntry(1000, 1000);
}
}
var Pass1 = Range(0, Height - 1);
var Pass2 = Range(Height - 1, 0);
foreach (var PassIterator in new[] { Pass1, Pass2 })
//foreach (var PassIterator in new[] { Pass1 })
{
for (int n = 0; n < Row.Length; n++) Row[n] = new DistanceEntry(1000, 1000);
//for (int y = 0; y < Height; y++)
foreach (var y in PassIterator)
{
for (int x = 0; x < Width; x++)
{
if (Mask[x, y])
{
// Inner
Row[x] = new DistanceEntry(0, 0);
// Left edge
if (x > 0 && !Mask[x - 1, y])
{
int DistanceX = 0, DistanceY = 0;
for (int x2 = x - 1; x2 >= 0; x2--)
{
if (Mask[x2, y]) break;
DistanceX--;
Row[x2].SetDistanceIfLower(new DistanceEntry(DistanceX, DistanceY));
}
}
// Right edge
if (x < Width - 1 && !Mask[x + 1, y])
{
int DistanceX = 0, DistanceY = 0;
for (int x2 = x + 1; x2 < Width; x2++)
{
if (Mask[x2, y]) break;
DistanceX++;
Row[x2].SetDistanceIfLower(new DistanceEntry(DistanceX, DistanceY));
}
}
}
else
{
//Row[x].SetDistanceIfLower(new DistanceEntry(1000, 1000));
}
}
for (int x = 0; x < Width; x++)
{
DistanceMap[x, y].SetDistanceIfLower(Row[x]);
Row[x] = DistanceMap[x, y];
//Console.Write("{0}", Row[x].GetChar());
}
#if true
for (int x = Width - 2; x >= 0; x--)
{
var Right = DistanceMap[x + 1, y];
DistanceMap[x, y].SetDistanceIfLower(new DistanceEntry(Right.DistanceX - 1, Right.DistanceY));
Row[x] = DistanceMap[x, y];
}
for (int x = 1; x < Width; x++)
{
var Right = DistanceMap[x - 1, y];
DistanceMap[x, y].SetDistanceIfLower(new DistanceEntry(Right.DistanceX + 1, Right.DistanceY));
Row[x] = DistanceMap[x, y];
}
#endif
//Console.WriteLine("");
for (int x = 0; x < Width; x++)
{
Row[x].DistanceY++;
//Console.Write("{0}", Row[x].GetChar());
}
}
}
return DistanceMap;
}