莫顿码
十进制的行列号(从0开始)转为十进制的莫顿码
/// <summary>
/// 十进制的行列号(从0开始)转为十进制的莫顿码
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
public static int CalcMorton(int row, int col)
{
var intLen = sizeof(int) * 8; // 32
int m = 0;
for (int i = 0; i < intLen; i++)
{
//var filter = 1 << i;//第i位上的过滤器(其余位必然为0)
//var a1 = col & filter;//对col进行过滤,只保留第i位上的值,其余位上统统为0
//var a2 = a1 << i;//将col从i位,左移i位,移动到2i位
//var b1 = row & filter;//对row进行过滤,只保留第i位上的值,其余位上统统为0
//var b2 = b1 << (i + 1);//将row从i位,左移i+1位,移动到2i+1位
//var c = a2 | b2;//将row和col合并(此时只有2i位和2i+1位上的值是有用的)
//m |= c;//再与前面低位(比2i位小的位)上的m合并
//简写为:
m |= (col & 1 << i) << i | (row & 1 << i) << (i + 1);
}
return m;
}
十进制的莫顿码转为十进制的行列号(从0开始)
/// <summary>
/// 将十进制的莫顿码转为十进制的行列号(从0开始)
/// </summary>
/// <param name="m"></param>
public static void FromMorton(int m, out int row, out int col)
{
row = 0;
col = 0;
var intLen = sizeof(int) * 8;//32
//先生成col
for (int i = 0; i < intLen; i++)
{
//var filter = 1 << (i + i);//第2i位上的过滤器(其余位必然为0)
//var a1 = m & filter;//对col进行过滤,只保留第2i位上的值,其余位上统统为0
//var a2 = a1 >> i;//将col从2i位,右移i位,移动到i位
//col |= a2;//再与前面低位(比2i位小的位)上的col合并
//简写:
col |= (m & 1 << (i + i))>> i;
}
//再生成row
for (int i = 0; i < intLen; i++)
{
//var filter = 1 << (i + i + 1);//第2i+1位上的过滤器(其余位必然为0)
//var a1 = m & filter;//对row进行过滤,只保留第2i位上的值,其余位上统统为0
//var a2 = a1 >> (i + 1);//将row从2i位,右移i+1位,移动到i位
//row |= a2;//再与前面低位(比2i位小的位)上的col合并
//简写:
row |= (m & 1 << (i + i + 1)) >> (i + 1);
}
}
简洁版(去掉解释)
/// <summary>
/// 十进制的行列号(从0开始)转为十进制的莫顿码
/// </summary>
/// <param name="row"></param>
/// <param name="col"></param>
/// <returns></returns>
public static int CalcMorton(int row, int col)
{
int m = 0;
for (int i = 0; i < 32; i++)
{
m |= (col & 1 << i) << i | (row & 1 << i) << (i + 1);
}
return m;
}
/// <summary>
/// 将十进制的莫顿码转为十进制的行列号(从0开始)
/// </summary>
/// <param name="m"></param>
public static void FromMorton(int m, out int row, out int col)
{
row = 0;
col = 0;
for (int i = 0; i < 32; i++)
{
col |= (m & 1 << (i + i))>> i;
}
for (int i = 0; i < 32; i++)
{
row |= (m & 1 << (i + i + 1)) >> (i + 1);
}
}