通过Doug T.的解决方案的启发我写了下面自己。 基本上我跑过矩阵两次(糟糕的表现:/)。我第一次在矩阵中的每个1
周围画墙,我用位掩码来做这个。我第二次清理了所有“向内指向”的墙。
示例设置:
// Add padding to output-matrix
int owidth = width+2;
int oheight = height+2;
// 4-bit value: 0bWSEN
static char N = 0x1; // The dash that goes from the center to the north
static char E = 0x2; // The dash that goes from the center to the east
static char S = 0x4; // ...
static char W = 0x8;
// This is what I will draw around every tile
char box[] =
{S|E, E|W, W|S,
N|S, 0 , N|S,
N|E, E|W, W|N };
的墙面循环:
for(unsigned int y = 0; y < height; y++)
for(unsigned int x = 0; x < width; x++)
{
// We ignore walls
if (! isOne(x, y)) // isOne takes care of out-of-bounds
continue;
// Go through neighbourhood
for(int dy = -1; dy <= 1; dy++)
for(int dx = -1; dx <= 1; dx++)
{
if (dy == 0 && dx == 0) // Ignore self
continue;
if (! isOne(x+dx, y+dy))
{
// Draw part of box
int ox = x+1, oy = y+1; // output-x and y
out[(oy+dy)*owidth+(ox+dx)] |= box[(dy+1)*3 + (dx+1)];
}
}
}
的清理循环:
// Clean up "pointing edges"
for(unsigned int y = 0; y < height; y++)
for(unsigned int x = 0; x < width; x++)
{
// We ignore zero's since we're only cleaning walls.
if (isOne(x, y))
continue;
int ox = x+1, oy = y+1; // output-x and y
// Remove edges that points to 'zero'-cells.
if (! isOne(x , y-1)) out[y*width+x] &= ~N;
if (! isOne(x , y+1)) out[y*width+x] &= ~S;
if (! isOne(x-1, y )) out[y*width+x] &= ~W;
if (! isOne(x+1, y )) out[y*width+x] &= ~E;
}
我然后有一个16大小(每个符号)查找列表,每个字符有一个条目。
map<unsigned int, wchar_t> p;
p[0] = ' ';
p[N] = '.';
// ...
p[N|S] = L'\u2502'; // │
p[E|W] = L'\u2500'; // ─
// ...
p[N|E|S|W] = L'\u253C'; // ┼
该算法的效率不高通过任何方式,O(2×宽×高)不好...它可以通过生成一个256大小查表正如其他建议加以改进,这将执行时给我们O(1)。
查找表将是典型的方式去这里,虽然从一个布尔数组工作需要一点点twiddling。我并不是完全清楚替代,但它看起来像1-> 1,而0 - > {4位值},所以可能有一定的压缩范围。正如R Pate在下面所说的那样,这似乎不值得。 – walkytalky 2009-11-16 19:02:39
您在替换部分(1-> 1,而0 - > {4位值})是正确的。是的,我当然必须回到更简单的解决方案,但我真的很好奇,看看有没有更好的解决方案...... – 2009-11-16 19:39:32
如何在输出中包围1的所有边看起来像? – 2009-11-16 23:40:35